1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <linux/reboot.h>
32 #include <sys/reboot.h>
33 #include <sys/socket.h>
37 #include "sd-daemon.h"
40 #include "alloc-util.h"
41 #include "bus-common-errors.h"
42 #include "bus-error.h"
43 #include "bus-message.h"
45 #include "cgroup-show.h"
46 #include "cgroup-util.h"
51 #include "exit-status.h"
54 #include "formats-util.h"
56 #include "glob-util.h"
57 #include "hostname-util.h"
62 #include "locale-util.h"
64 #include "logs-show.h"
68 #include "parse-util.h"
69 #include "path-lookup.h"
70 #include "path-util.h"
71 #include "process-util.h"
72 #include "rlimit-util.h"
74 #include "signal-util.h"
75 #include "socket-util.h"
76 #include "spawn-ask-password-agent.h"
77 #include "spawn-polkit-agent.h"
79 #include "stat-util.h"
81 #include "terminal-util.h"
82 #include "unit-name.h"
83 #include "user-util.h"
85 #include "utmp-wtmp.h"
89 static char **arg_types
= NULL
;
90 static char **arg_states
= NULL
;
91 static char **arg_properties
= NULL
;
92 static bool arg_all
= false;
93 static enum dependency
{
99 } arg_dependency
= DEPENDENCY_FORWARD
;
100 static const char *arg_job_mode
= "replace";
101 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
102 static bool arg_no_block
= false;
103 static bool arg_no_legend
= false;
104 static bool arg_no_pager
= false;
105 static bool arg_no_wtmp
= false;
106 static bool arg_no_wall
= false;
107 static bool arg_no_reload
= false;
108 static bool arg_show_types
= false;
109 static bool arg_ignore_inhibitors
= false;
110 static bool arg_dry
= false;
111 static bool arg_quiet
= false;
112 static bool arg_full
= false;
113 static bool arg_recursive
= false;
114 static int arg_force
= 0;
115 static bool arg_ask_password
= false;
116 static bool arg_runtime
= false;
117 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
118 static char **arg_wall
= NULL
;
119 static const char *arg_kill_who
= NULL
;
120 static int arg_signal
= SIGTERM
;
121 static char *arg_root
= NULL
;
122 static usec_t arg_when
= 0;
144 ACTION_CANCEL_SHUTDOWN
,
146 } arg_action
= ACTION_SYSTEMCTL
;
147 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
148 static const char *arg_host
= NULL
;
149 static unsigned arg_lines
= 10;
150 static OutputMode arg_output
= OUTPUT_SHORT
;
151 static bool arg_plain
= false;
152 static bool arg_firmware_setup
= false;
153 static bool arg_now
= false;
155 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
156 static int halt_now(enum action a
);
157 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
159 static bool original_stdout_is_tty
;
161 typedef enum BusFocus
{
162 BUS_FULL
, /* The full bus indicated via --system or --user */
163 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
167 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
169 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
172 assert(focus
< _BUS_FOCUS_MAX
);
175 /* We only go directly to the manager, if we are using a local transport */
176 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
179 if (!busses
[focus
]) {
182 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
184 if (focus
== BUS_MANAGER
)
185 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
187 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
189 return log_error_errno(r
, "Failed to connect to bus: %m");
191 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
194 *ret
= busses
[focus
];
198 static void release_busses(void) {
201 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
202 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
205 static void pager_open_if_enabled(void) {
213 static void ask_password_agent_open_if_enabled(void) {
215 /* Open the password agent as a child process if necessary */
217 if (!arg_ask_password
)
220 if (arg_scope
!= UNIT_FILE_SYSTEM
)
223 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
226 ask_password_agent_open();
229 static void polkit_agent_open_if_enabled(void) {
231 /* Open the polkit agent as a child process if necessary */
233 if (!arg_ask_password
)
236 if (arg_scope
!= UNIT_FILE_SYSTEM
)
239 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
245 static OutputFlags
get_output_flags(void) {
247 arg_all
* OUTPUT_SHOW_ALL
|
248 arg_full
* OUTPUT_FULL_WIDTH
|
249 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
250 on_tty() * OUTPUT_COLOR
|
251 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
254 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
257 if (!sd_bus_error_is_set(error
))
260 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
261 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
262 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
263 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
264 return EXIT_NOPERMISSION
;
266 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
267 return EXIT_NOTINSTALLED
;
269 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
270 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
271 return EXIT_NOTIMPLEMENTED
;
273 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
274 return EXIT_NOTCONFIGURED
;
282 static bool install_client_side(void) {
284 /* Decides when to execute enable/disable/... operations
285 * client-side rather than server-side. */
287 if (running_in_chroot() > 0)
290 if (sd_booted() <= 0)
293 if (!isempty(arg_root
))
296 if (arg_scope
== UNIT_FILE_GLOBAL
)
302 static int compare_unit_info(const void *a
, const void *b
) {
303 const UnitInfo
*u
= a
, *v
= b
;
307 /* First, order by machine */
308 if (!u
->machine
&& v
->machine
)
310 if (u
->machine
&& !v
->machine
)
312 if (u
->machine
&& v
->machine
) {
313 r
= strcasecmp(u
->machine
, v
->machine
);
318 /* Second, order by unit type */
319 d1
= strrchr(u
->id
, '.');
320 d2
= strrchr(v
->id
, '.');
322 r
= strcasecmp(d1
, d2
);
327 /* Third, order by name */
328 return strcasecmp(u
->id
, v
->id
);
331 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
332 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
338 dot
= strrchr(u
->id
, '.');
342 if (!strv_find(arg_types
, dot
+1))
352 if (streq(u
->active_state
, "inactive") || u
->following
[0])
358 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
359 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
361 unsigned n_shown
= 0;
364 max_id_len
= strlen("UNIT");
365 load_len
= strlen("LOAD");
366 active_len
= strlen("ACTIVE");
367 sub_len
= strlen("SUB");
368 job_len
= strlen("JOB");
371 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
372 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
373 load_len
= MAX(load_len
, strlen(u
->load_state
));
374 active_len
= MAX(active_len
, strlen(u
->active_state
));
375 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
377 if (u
->job_id
!= 0) {
378 job_len
= MAX(job_len
, strlen(u
->job_type
));
382 if (!arg_no_legend
&&
383 (streq(u
->active_state
, "failed") ||
384 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
388 if (!arg_full
&& original_stdout_is_tty
) {
391 id_len
= MIN(max_id_len
, 25u);
392 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
395 basic_len
+= job_len
+ 1;
397 if (basic_len
< (unsigned) columns()) {
398 unsigned extra_len
, incr
;
399 extra_len
= columns() - basic_len
;
401 /* Either UNIT already got 25, or is fully satisfied.
402 * Grant up to 25 to DESC now. */
403 incr
= MIN(extra_len
, 25u);
407 /* split the remaining space between UNIT and DESC,
408 * but do not give UNIT more than it needs. */
410 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
412 desc_len
+= extra_len
- incr
;
418 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
419 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
420 const char *on_loaded
= "", *off_loaded
= "";
421 const char *on_active
= "", *off_active
= "";
422 const char *on_circle
= "", *off_circle
= "";
426 if (!n_shown
&& !arg_no_legend
) {
431 printf("%-*s %-*s %-*s %-*s ",
434 active_len
, "ACTIVE",
438 printf("%-*s ", job_len
, "JOB");
440 if (!arg_full
&& arg_no_pager
)
441 printf("%.*s\n", desc_len
, "DESCRIPTION");
443 printf("%s\n", "DESCRIPTION");
448 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
449 on_loaded
= ansi_highlight_red();
450 on_circle
= ansi_highlight_yellow();
451 off_loaded
= off_circle
= ansi_normal();
453 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
454 on_circle
= on_active
= ansi_highlight_red();
455 off_circle
= off_active
= ansi_normal();
460 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
469 e
= ellipsize(id
, id_len
, 33);
477 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
479 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
480 on_active
, id_len
, id
, off_active
,
481 on_loaded
, load_len
, u
->load_state
, off_loaded
,
482 on_active
, active_len
, u
->active_state
,
483 sub_len
, u
->sub_state
, off_active
,
484 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
487 printf("%.*s\n", desc_len
, u
->description
);
489 printf("%s\n", u
->description
);
492 if (!arg_no_legend
) {
493 const char *on
, *off
;
497 "LOAD = Reflects whether the unit definition was properly loaded.\n"
498 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
499 "SUB = The low-level unit activation state, values depend on unit type.");
500 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
501 on
= ansi_highlight();
504 on
= ansi_highlight_red();
509 printf("%s%u loaded units listed.%s\n"
510 "To show all installed unit files use 'systemctl list-unit-files'.\n",
513 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
514 "To show all installed unit files use 'systemctl list-unit-files'.\n",
521 static int get_unit_list(
525 UnitInfo
**unit_infos
,
527 sd_bus_message
**_reply
) {
529 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
530 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
531 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
540 r
= sd_bus_message_new_method_call(
543 "org.freedesktop.systemd1",
544 "/org/freedesktop/systemd1",
545 "org.freedesktop.systemd1.Manager",
546 "ListUnitsFiltered");
549 return bus_log_create_error(r
);
551 r
= sd_bus_message_append_strv(m
, arg_states
);
553 return bus_log_create_error(r
);
555 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
557 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
559 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
561 return bus_log_parse_error(r
);
563 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
566 if (!output_show_unit(&u
, patterns
))
569 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
572 (*unit_infos
)[c
++] = u
;
575 return bus_log_parse_error(r
);
577 r
= sd_bus_message_exit_container(reply
);
579 return bus_log_parse_error(r
);
587 static void message_set_freep(Set
**set
) {
590 while ((m
= set_steal_first(*set
)))
591 sd_bus_message_unref(m
);
596 static int get_unit_list_recursive(
599 UnitInfo
**_unit_infos
,
603 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
604 _cleanup_(message_set_freep
) Set
*replies
;
605 sd_bus_message
*reply
;
613 replies
= set_new(NULL
);
617 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
621 r
= set_put(replies
, reply
);
623 sd_bus_message_unref(reply
);
628 _cleanup_strv_free_
char **machines
= NULL
;
631 r
= sd_get_machine_names(&machines
);
633 return log_error_errno(r
, "Failed to get machine names: %m");
635 STRV_FOREACH(i
, machines
) {
636 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
639 r
= sd_bus_open_system_machine(&container
, *i
);
641 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
645 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
651 r
= set_put(replies
, reply
);
653 sd_bus_message_unref(reply
);
658 *_machines
= machines
;
663 *_unit_infos
= unit_infos
;
672 static int list_units(int argc
, char *argv
[], void *userdata
) {
673 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
674 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
675 _cleanup_strv_free_
char **machines
= NULL
;
679 pager_open_if_enabled();
681 r
= acquire_bus(BUS_MANAGER
, &bus
);
685 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
689 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
690 return output_units_list(unit_infos
, r
);
693 static int get_triggered_units(
698 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
705 r
= sd_bus_get_property_strv(
707 "org.freedesktop.systemd1",
709 "org.freedesktop.systemd1.Unit",
714 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
719 static int get_listening(
721 const char* unit_path
,
724 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
725 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
726 const char *type
, *path
;
729 r
= sd_bus_get_property(
731 "org.freedesktop.systemd1",
733 "org.freedesktop.systemd1.Socket",
739 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
741 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
743 return bus_log_parse_error(r
);
745 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
747 r
= strv_extend(listening
, type
);
751 r
= strv_extend(listening
, path
);
758 return bus_log_parse_error(r
);
760 r
= sd_bus_message_exit_container(reply
);
762 return bus_log_parse_error(r
);
774 /* Note: triggered is a list here, although it almost certainly
775 * will always be one unit. Nevertheless, dbus API allows for multiple
776 * values, so let's follow that. */
779 /* The strv above is shared. free is set only in the first one. */
783 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
789 if (!a
->machine
&& b
->machine
)
791 if (a
->machine
&& !b
->machine
)
793 if (a
->machine
&& b
->machine
) {
794 o
= strcasecmp(a
->machine
, b
->machine
);
799 o
= strcmp(a
->path
, b
->path
);
801 o
= strcmp(a
->type
, b
->type
);
806 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
807 struct socket_info
*s
;
808 unsigned pathlen
= strlen("LISTEN"),
809 typelen
= strlen("TYPE") * arg_show_types
,
810 socklen
= strlen("UNIT"),
811 servlen
= strlen("ACTIVATES");
812 const char *on
, *off
;
814 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
818 socklen
= MAX(socklen
, strlen(s
->id
));
820 typelen
= MAX(typelen
, strlen(s
->type
));
821 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
823 STRV_FOREACH(a
, s
->triggered
)
824 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
825 servlen
= MAX(servlen
, tmp
);
830 printf("%-*s %-*.*s%-*s %s\n",
832 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
836 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
837 _cleanup_free_
char *j
= NULL
;
842 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
850 printf("%-*s %-*s %-*s",
851 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
854 pathlen
, path
, socklen
, s
->id
);
855 STRV_FOREACH(a
, s
->triggered
)
857 a
== s
->triggered
? "" : ",", *a
);
861 on
= ansi_highlight();
866 on
= ansi_highlight_red();
870 if (!arg_no_legend
) {
871 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
873 printf("Pass --all to see loaded but inactive sockets, too.\n");
879 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
880 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
881 _cleanup_strv_free_
char **machines
= NULL
;
882 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
883 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
885 struct socket_info
*s
;
891 pager_open_if_enabled();
893 r
= acquire_bus(BUS_MANAGER
, &bus
);
897 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
901 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
902 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
905 if (!endswith(u
->id
, ".socket"))
908 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
912 c
= get_listening(bus
, u
->unit_path
, &listening
);
918 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
923 for (i
= 0; i
< c
; i
++)
924 socket_infos
[cs
+ i
] = (struct socket_info
) {
925 .machine
= u
->machine
,
927 .type
= listening
[i
*2],
928 .path
= listening
[i
*2 + 1],
929 .triggered
= triggered
,
930 .own_triggered
= i
==0,
933 /* from this point on we will cleanup those socket_infos */
936 listening
= triggered
= NULL
; /* avoid cleanup */
939 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
940 (__compar_fn_t
) socket_info_compare
);
942 output_sockets_list(socket_infos
, cs
);
945 assert(cs
== 0 || socket_infos
);
946 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
949 if (s
->own_triggered
)
950 strv_free(s
->triggered
);
956 static int get_next_elapse(
959 dual_timestamp
*next
) {
961 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
969 r
= sd_bus_get_property_trivial(
971 "org.freedesktop.systemd1",
973 "org.freedesktop.systemd1.Timer",
974 "NextElapseUSecMonotonic",
979 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
981 r
= sd_bus_get_property_trivial(
983 "org.freedesktop.systemd1",
985 "org.freedesktop.systemd1.Timer",
986 "NextElapseUSecRealtime",
991 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
997 static int get_last_trigger(
1002 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1009 r
= sd_bus_get_property_trivial(
1011 "org.freedesktop.systemd1",
1013 "org.freedesktop.systemd1.Timer",
1019 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1025 const char* machine
;
1028 usec_t last_trigger
;
1032 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1038 if (!a
->machine
&& b
->machine
)
1040 if (a
->machine
&& !b
->machine
)
1042 if (a
->machine
&& b
->machine
) {
1043 o
= strcasecmp(a
->machine
, b
->machine
);
1048 if (a
->next_elapse
< b
->next_elapse
)
1050 if (a
->next_elapse
> b
->next_elapse
)
1053 return strcmp(a
->id
, b
->id
);
1056 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1057 struct timer_info
*t
;
1059 nextlen
= strlen("NEXT"),
1060 leftlen
= strlen("LEFT"),
1061 lastlen
= strlen("LAST"),
1062 passedlen
= strlen("PASSED"),
1063 unitlen
= strlen("UNIT"),
1064 activatelen
= strlen("ACTIVATES");
1066 const char *on
, *off
;
1068 assert(timer_infos
|| n
== 0);
1070 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1074 if (t
->next_elapse
> 0) {
1075 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1077 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1078 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1080 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1081 leftlen
= MAX(leftlen
, strlen(trel
));
1084 if (t
->last_trigger
> 0) {
1085 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1087 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1088 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1090 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1091 passedlen
= MAX(passedlen
, strlen(trel
));
1094 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1096 STRV_FOREACH(a
, t
->triggered
)
1097 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1099 activatelen
= MAX(activatelen
, ul
);
1104 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1108 passedlen
, "PASSED",
1112 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1113 _cleanup_free_
char *j
= NULL
;
1115 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1116 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1119 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1120 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1122 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1123 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1126 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1133 printf("%-*s %-*s %-*s %-*s %-*s",
1134 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1136 STRV_FOREACH(a
, t
->triggered
)
1138 a
== t
->triggered
? "" : ",", *a
);
1142 on
= ansi_highlight();
1143 off
= ansi_normal();
1147 on
= ansi_highlight_red();
1148 off
= ansi_normal();
1151 if (!arg_no_legend
) {
1152 printf("%s%u timers listed.%s\n", on
, n
, off
);
1154 printf("Pass --all to see loaded but inactive timers, too.\n");
1160 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1166 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1169 if (next
->monotonic
> nw
->monotonic
)
1170 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1172 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1174 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1175 next_elapse
= MIN(converted
, next
->realtime
);
1177 next_elapse
= converted
;
1180 next_elapse
= next
->realtime
;
1185 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1186 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1187 _cleanup_strv_free_
char **machines
= NULL
;
1188 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1189 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1190 struct timer_info
*t
;
1198 pager_open_if_enabled();
1200 r
= acquire_bus(BUS_MANAGER
, &bus
);
1204 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1208 dual_timestamp_get(&nw
);
1210 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1211 _cleanup_strv_free_
char **triggered
= NULL
;
1212 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1215 if (!endswith(u
->id
, ".timer"))
1218 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1222 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1226 get_last_trigger(bus
, u
->unit_path
, &last
);
1228 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1233 m
= calc_next_elapse(&nw
, &next
);
1235 timer_infos
[c
++] = (struct timer_info
) {
1236 .machine
= u
->machine
,
1239 .last_trigger
= last
,
1240 .triggered
= triggered
,
1243 triggered
= NULL
; /* avoid cleanup */
1246 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1247 (__compar_fn_t
) timer_info_compare
);
1249 output_timers_list(timer_infos
, c
);
1252 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1253 strv_free(t
->triggered
);
1258 static int compare_unit_file_list(const void *a
, const void *b
) {
1259 const char *d1
, *d2
;
1260 const UnitFileList
*u
= a
, *v
= b
;
1262 d1
= strrchr(u
->path
, '.');
1263 d2
= strrchr(v
->path
, '.');
1268 r
= strcasecmp(d1
, d2
);
1273 return strcasecmp(basename(u
->path
), basename(v
->path
));
1276 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1277 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1280 if (!strv_isempty(arg_types
)) {
1283 dot
= strrchr(u
->path
, '.');
1287 if (!strv_find(arg_types
, dot
+1))
1291 if (!strv_isempty(arg_states
) &&
1292 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1298 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1299 unsigned max_id_len
, id_cols
, state_cols
;
1300 const UnitFileList
*u
;
1302 max_id_len
= strlen("UNIT FILE");
1303 state_cols
= strlen("STATE");
1305 for (u
= units
; u
< units
+ c
; u
++) {
1306 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1307 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1311 unsigned basic_cols
;
1313 id_cols
= MIN(max_id_len
, 25u);
1314 basic_cols
= 1 + id_cols
+ state_cols
;
1315 if (basic_cols
< (unsigned) columns())
1316 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1318 id_cols
= max_id_len
;
1321 printf("%-*s %-*s\n",
1322 id_cols
, "UNIT FILE",
1323 state_cols
, "STATE");
1325 for (u
= units
; u
< units
+ c
; u
++) {
1326 _cleanup_free_
char *e
= NULL
;
1327 const char *on
, *off
;
1330 if (IN_SET(u
->state
,
1332 UNIT_FILE_MASKED_RUNTIME
,
1334 UNIT_FILE_INVALID
)) {
1335 on
= ansi_highlight_red();
1336 off
= ansi_normal();
1337 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1338 on
= ansi_highlight_green();
1339 off
= ansi_normal();
1343 id
= basename(u
->path
);
1345 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1347 printf("%-*s %s%-*s%s\n",
1348 id_cols
, e
? e
: id
,
1349 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1353 printf("\n%u unit files listed.\n", c
);
1356 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1357 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1358 _cleanup_free_ UnitFileList
*units
= NULL
;
1366 pager_open_if_enabled();
1368 if (install_client_side()) {
1374 h
= hashmap_new(&string_hash_ops
);
1378 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1380 unit_file_list_free(h
);
1381 return log_error_errno(r
, "Failed to get unit file list: %m");
1384 n_units
= hashmap_size(h
);
1386 units
= new(UnitFileList
, n_units
);
1387 if (!units
&& n_units
> 0) {
1388 unit_file_list_free(h
);
1392 HASHMAP_FOREACH(u
, h
, i
) {
1393 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1400 assert(c
<= n_units
);
1403 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1406 r
= acquire_bus(BUS_MANAGER
, &bus
);
1410 r
= sd_bus_call_method(
1412 "org.freedesktop.systemd1",
1413 "/org/freedesktop/systemd1",
1414 "org.freedesktop.systemd1.Manager",
1420 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1422 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1424 return bus_log_parse_error(r
);
1426 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1428 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1431 units
[c
] = (struct UnitFileList
) {
1433 unit_file_state_from_string(state
)
1436 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1441 return bus_log_parse_error(r
);
1443 r
= sd_bus_message_exit_container(reply
);
1445 return bus_log_parse_error(r
);
1448 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1449 output_unit_file_list(units
, c
);
1451 if (install_client_side()) {
1452 for (unit
= units
; unit
< units
+ c
; unit
++)
1459 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1460 _cleanup_free_
char *n
= NULL
;
1461 size_t max_len
= MAX(columns(),20u);
1467 for (i
= level
- 1; i
>= 0; i
--) {
1469 if (len
> max_len
- 3 && !arg_full
) {
1470 printf("%s...\n",max_len
% 2 ? "" : " ");
1473 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1477 if (len
> max_len
- 3 && !arg_full
) {
1478 printf("%s...\n",max_len
% 2 ? "" : " ");
1482 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1486 printf("%s\n", name
);
1490 n
= ellipsize(name
, max_len
-len
, 100);
1498 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1500 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1501 [DEPENDENCY_FORWARD
] = "Requires\0"
1502 "RequiresOverridable\0"
1504 "RequisiteOverridable\0"
1508 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1509 "RequiredByOverridable\0"
1511 "RequisiteOfOverridable\0"
1515 [DEPENDENCY_AFTER
] = "After\0",
1516 [DEPENDENCY_BEFORE
] = "Before\0",
1519 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1520 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1521 _cleanup_strv_free_
char **ret
= NULL
;
1522 _cleanup_free_
char *path
= NULL
;
1528 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1530 path
= unit_dbus_path_from_name(name
);
1534 r
= sd_bus_call_method(
1536 "org.freedesktop.systemd1",
1538 "org.freedesktop.DBus.Properties",
1542 "s", "org.freedesktop.systemd1.Unit");
1544 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1546 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1548 return bus_log_parse_error(r
);
1550 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1553 r
= sd_bus_message_read(reply
, "s", &prop
);
1555 return bus_log_parse_error(r
);
1557 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1558 r
= sd_bus_message_skip(reply
, "v");
1560 return bus_log_parse_error(r
);
1563 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1565 return bus_log_parse_error(r
);
1567 r
= bus_message_read_strv_extend(reply
, &ret
);
1569 return bus_log_parse_error(r
);
1571 r
= sd_bus_message_exit_container(reply
);
1573 return bus_log_parse_error(r
);
1576 r
= sd_bus_message_exit_container(reply
);
1578 return bus_log_parse_error(r
);
1582 return bus_log_parse_error(r
);
1584 r
= sd_bus_message_exit_container(reply
);
1586 return bus_log_parse_error(r
);
1594 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1595 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1597 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1599 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1602 return strcasecmp(*a
, *b
);
1605 static int list_dependencies_one(
1610 unsigned int branches
) {
1612 _cleanup_strv_free_
char **deps
= NULL
;
1620 r
= strv_extend(units
, name
);
1624 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1628 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1630 STRV_FOREACH(c
, deps
) {
1631 if (strv_contains(*units
, *c
)) {
1633 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1646 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1647 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1648 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1651 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1655 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1656 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1663 strv_remove(*units
, name
);
1668 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1669 _cleanup_strv_free_
char **units
= NULL
;
1670 _cleanup_free_
char *unit
= NULL
;
1676 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1678 return log_error_errno(r
, "Failed to mangle unit name: %m");
1682 u
= SPECIAL_DEFAULT_TARGET
;
1684 pager_open_if_enabled();
1686 r
= acquire_bus(BUS_MANAGER
, &bus
);
1692 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1695 struct machine_info
{
1699 char *control_group
;
1700 uint32_t n_failed_units
;
1705 static const struct bus_properties_map machine_info_property_map
[] = {
1706 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1707 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1708 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1709 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1710 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1714 static void machine_info_clear(struct machine_info
*info
) {
1718 free(info
->control_group
);
1723 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1729 for (i
= 0; i
< n
; i
++)
1730 machine_info_clear(&machine_infos
[i
]);
1732 free(machine_infos
);
1735 static int compare_machine_info(const void *a
, const void *b
) {
1736 const struct machine_info
*u
= a
, *v
= b
;
1738 if (u
->is_host
!= v
->is_host
)
1739 return u
->is_host
> v
->is_host
? -1 : 1;
1741 return strcasecmp(u
->name
, v
->name
);
1744 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1745 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1751 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1758 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1765 static bool output_show_machine(const char *name
, char **patterns
) {
1766 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1769 static int get_machine_list(
1771 struct machine_info
**_machine_infos
,
1774 struct machine_info
*machine_infos
= NULL
;
1775 _cleanup_strv_free_
char **m
= NULL
;
1776 _cleanup_free_
char *hn
= NULL
;
1781 hn
= gethostname_malloc();
1785 if (output_show_machine(hn
, patterns
)) {
1786 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1789 machine_infos
[c
].is_host
= true;
1790 machine_infos
[c
].name
= hn
;
1793 get_machine_properties(bus
, &machine_infos
[c
]);
1797 r
= sd_get_machine_names(&m
);
1799 return log_error_errno(r
, "Failed to get machine list: %m");
1801 STRV_FOREACH(i
, m
) {
1802 _cleanup_free_
char *class = NULL
;
1804 if (!output_show_machine(*i
, patterns
))
1807 sd_machine_get_class(*i
, &class);
1808 if (!streq_ptr(class, "container"))
1811 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1812 free_machines_list(machine_infos
, c
);
1816 machine_infos
[c
].is_host
= false;
1817 machine_infos
[c
].name
= strdup(*i
);
1818 if (!machine_infos
[c
].name
) {
1819 free_machines_list(machine_infos
, c
);
1823 get_machine_properties(NULL
, &machine_infos
[c
]);
1827 *_machine_infos
= machine_infos
;
1831 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1832 struct machine_info
*m
;
1835 namelen
= sizeof("NAME") - 1,
1836 statelen
= sizeof("STATE") - 1,
1837 failedlen
= sizeof("FAILED") - 1,
1838 jobslen
= sizeof("JOBS") - 1;
1840 assert(machine_infos
|| n
== 0);
1842 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1843 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1844 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1845 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1846 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1848 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1852 if (!arg_no_legend
) {
1856 printf("%-*s %-*s %-*s %-*s\n",
1859 failedlen
, "FAILED",
1863 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1864 const char *on_state
= "", *off_state
= "";
1865 const char *on_failed
= "", *off_failed
= "";
1866 bool circle
= false;
1868 if (streq_ptr(m
->state
, "degraded")) {
1869 on_state
= ansi_highlight_red();
1870 off_state
= ansi_normal();
1872 } else if (!streq_ptr(m
->state
, "running")) {
1873 on_state
= ansi_highlight_yellow();
1874 off_state
= ansi_normal();
1878 if (m
->n_failed_units
> 0) {
1879 on_failed
= ansi_highlight_red();
1880 off_failed
= ansi_normal();
1882 on_failed
= off_failed
= "";
1885 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1888 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1889 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1890 on_state
, statelen
, strna(m
->state
), off_state
,
1891 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1892 jobslen
, m
->n_jobs
);
1894 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1895 namelen
, strna(m
->name
),
1896 on_state
, statelen
, strna(m
->state
), off_state
,
1897 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1898 jobslen
, m
->n_jobs
);
1902 printf("\n%u machines listed.\n", n
);
1905 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1906 struct machine_info
*machine_infos
= NULL
;
1910 if (geteuid() != 0) {
1911 log_error("Must be root.");
1915 pager_open_if_enabled();
1917 r
= acquire_bus(BUS_MANAGER
, &bus
);
1921 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1925 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1926 output_machines_list(machine_infos
, r
);
1927 free_machines_list(machine_infos
, r
);
1932 static int get_default(int argc
, char *argv
[], void *userdata
) {
1933 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1934 _cleanup_free_
char *_path
= NULL
;
1938 if (install_client_side()) {
1939 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1941 return log_error_errno(r
, "Failed to get default target: %m");
1945 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1948 r
= acquire_bus(BUS_MANAGER
, &bus
);
1952 r
= sd_bus_call_method(
1954 "org.freedesktop.systemd1",
1955 "/org/freedesktop/systemd1",
1956 "org.freedesktop.systemd1.Manager",
1962 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1964 r
= sd_bus_message_read(reply
, "s", &path
);
1966 return bus_log_parse_error(r
);
1970 printf("%s\n", path
);
1975 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1978 assert(changes
|| n_changes
== 0);
1980 for (i
= 0; i
< n_changes
; i
++) {
1981 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1982 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1984 log_info("Removed symlink %s.", changes
[i
].path
);
1988 static int set_default(int argc
, char *argv
[], void *userdata
) {
1989 _cleanup_free_
char *unit
= NULL
;
1995 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1997 return log_error_errno(r
, "Failed to mangle unit name: %m");
1999 if (install_client_side()) {
2000 UnitFileChange
*changes
= NULL
;
2001 unsigned n_changes
= 0;
2003 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2005 return log_error_errno(r
, "Failed to set default target: %m");
2008 dump_unit_file_changes(changes
, n_changes
);
2010 unit_file_changes_free(changes
, n_changes
);
2013 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2014 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2017 polkit_agent_open_if_enabled();
2019 r
= acquire_bus(BUS_MANAGER
, &bus
);
2023 r
= sd_bus_call_method(
2025 "org.freedesktop.systemd1",
2026 "/org/freedesktop/systemd1",
2027 "org.freedesktop.systemd1.Manager",
2033 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2035 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2039 /* Try to reload if enabled */
2041 r
= daemon_reload(argc
, argv
, userdata
);
2051 const char *name
, *type
, *state
;
2054 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2055 unsigned id_len
, unit_len
, type_len
, state_len
;
2056 const struct job_info
*j
;
2057 const char *on
, *off
;
2058 bool shorten
= false;
2060 assert(n
== 0 || jobs
);
2063 if (!arg_no_legend
) {
2064 on
= ansi_highlight_green();
2065 off
= ansi_normal();
2067 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2072 pager_open_if_enabled();
2074 id_len
= strlen("JOB");
2075 unit_len
= strlen("UNIT");
2076 type_len
= strlen("TYPE");
2077 state_len
= strlen("STATE");
2079 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2080 uint32_t id
= j
->id
;
2081 assert(j
->name
&& j
->type
&& j
->state
);
2083 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2084 unit_len
= MAX(unit_len
, strlen(j
->name
));
2085 type_len
= MAX(type_len
, strlen(j
->type
));
2086 state_len
= MAX(state_len
, strlen(j
->state
));
2089 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2090 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2095 printf("%*s %-*s %-*s %-*s\n",
2099 state_len
, "STATE");
2101 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2102 _cleanup_free_
char *e
= NULL
;
2104 if (streq(j
->state
, "running")) {
2105 on
= ansi_highlight();
2106 off
= ansi_normal();
2110 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2111 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2113 on
, unit_len
, e
? e
: j
->name
, off
,
2115 on
, state_len
, j
->state
, off
);
2118 if (!arg_no_legend
) {
2119 on
= ansi_highlight();
2120 off
= ansi_normal();
2122 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2126 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2127 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2130 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2131 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2132 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2133 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2134 _cleanup_free_
struct job_info
*jobs
= NULL
;
2140 bool skipped
= false;
2142 pager_open_if_enabled();
2144 r
= acquire_bus(BUS_MANAGER
, &bus
);
2148 r
= sd_bus_call_method(
2150 "org.freedesktop.systemd1",
2151 "/org/freedesktop/systemd1",
2152 "org.freedesktop.systemd1.Manager",
2158 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2160 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2162 return bus_log_parse_error(r
);
2164 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2165 struct job_info job
= { id
, name
, type
, state
};
2167 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2172 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2178 return bus_log_parse_error(r
);
2180 r
= sd_bus_message_exit_container(reply
);
2182 return bus_log_parse_error(r
);
2184 output_jobs_list(jobs
, c
, skipped
);
2188 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2194 return daemon_reload(argc
, argv
, userdata
);
2196 polkit_agent_open_if_enabled();
2198 r
= acquire_bus(BUS_MANAGER
, &bus
);
2202 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2203 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2207 q
= safe_atou32(*name
, &id
);
2209 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2211 q
= sd_bus_call_method(
2213 "org.freedesktop.systemd1",
2214 "/org/freedesktop/systemd1",
2215 "org.freedesktop.systemd1.Manager",
2221 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2230 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2231 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2235 /* We ignore all errors here, since this is used to show a
2238 /* We don't use unit_dbus_path_from_name() directly since we
2239 * don't want to load the unit if it isn't loaded. */
2241 r
= sd_bus_call_method(
2243 "org.freedesktop.systemd1",
2244 "/org/freedesktop/systemd1",
2245 "org.freedesktop.systemd1.Manager",
2253 r
= sd_bus_message_read(reply
, "o", &path
);
2257 r
= sd_bus_get_property_trivial(
2259 "org.freedesktop.systemd1",
2261 "org.freedesktop.systemd1.Unit",
2271 static void warn_unit_file_changed(const char *name
) {
2272 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2273 ansi_highlight_red(),
2276 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2279 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2286 STRV_FOREACH(p
, lp
->unit_path
) {
2287 _cleanup_free_
char *path
;
2289 path
= path_join(arg_root
, *p
, unit_name
);
2293 if (access(path
, F_OK
) == 0) {
2303 static int unit_find_paths(
2305 const char *unit_name
,
2307 char **fragment_path
,
2308 char ***dropin_paths
) {
2310 _cleanup_free_
char *path
= NULL
;
2311 _cleanup_strv_free_
char **dropins
= NULL
;
2315 * Finds where the unit is defined on disk. Returns 0 if the unit
2316 * is not found. Returns 1 if it is found, and sets
2317 * - the path to the unit in *path, if it exists on disk,
2318 * - and a strv of existing drop-ins in *dropins,
2319 * if the arg is not NULL and any dropins were found.
2323 assert(fragment_path
);
2326 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2327 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2328 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2329 _cleanup_free_
char *unit
= NULL
;
2330 char *unit_load_error_name
, *unit_load_error_message
;
2332 unit
= unit_dbus_path_from_name(unit_name
);
2336 if (need_daemon_reload(bus
, unit_name
) > 0)
2337 warn_unit_file_changed(unit_name
);
2339 r
= sd_bus_get_property(
2341 "org.freedesktop.systemd1",
2343 "org.freedesktop.systemd1.Unit",
2349 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2351 r
= sd_bus_message_read(
2354 &unit_load_error_name
,
2355 &unit_load_error_message
);
2357 return bus_log_parse_error(r
);
2359 if (!isempty(unit_load_error_name
)) {
2360 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2364 r
= sd_bus_get_property_string(
2366 "org.freedesktop.systemd1",
2368 "org.freedesktop.systemd1.Unit",
2373 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2376 r
= sd_bus_get_property_strv(
2378 "org.freedesktop.systemd1",
2380 "org.freedesktop.systemd1.Unit",
2385 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2388 _cleanup_set_free_ Set
*names
;
2390 names
= set_new(NULL
);
2394 r
= set_put(names
, unit_name
);
2396 return log_error_errno(r
, "Failed to add unit name: %m");
2398 r
= unit_file_find_path(lp
, unit_name
, &path
);
2403 _cleanup_free_
char *template = NULL
;
2405 r
= unit_name_template(unit_name
, &template);
2406 if (r
< 0 && r
!= -EINVAL
)
2407 return log_error_errno(r
, "Failed to determine template name: %m");
2409 r
= unit_file_find_path(lp
, template, &path
);
2416 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2424 if (!isempty(path
)) {
2425 *fragment_path
= path
;
2430 if (dropin_paths
&& !strv_isempty(dropins
)) {
2431 *dropin_paths
= dropins
;
2437 log_error("No files found for %s.", unit_name
);
2442 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2443 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2444 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2450 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2452 return log_error_errno(r
, "Failed to mangle unit name: %m");
2454 /* We don't use unit_dbus_path_from_name() directly since we
2455 * don't want to load the unit if it isn't loaded. */
2457 r
= sd_bus_call_method(
2459 "org.freedesktop.systemd1",
2460 "/org/freedesktop/systemd1",
2461 "org.freedesktop.systemd1.Manager",
2472 r
= sd_bus_message_read(reply
, "o", &path
);
2474 return bus_log_parse_error(r
);
2476 r
= sd_bus_get_property_string(
2478 "org.freedesktop.systemd1",
2480 "org.freedesktop.systemd1.Unit",
2493 return nulstr_contains(good_states
, state
);
2496 static int check_triggering_units(
2500 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2501 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2502 _cleanup_strv_free_
char **triggered_by
= NULL
;
2503 bool print_warning_label
= true;
2507 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2509 return log_error_errno(r
, "Failed to mangle unit name: %m");
2511 path
= unit_dbus_path_from_name(n
);
2515 r
= sd_bus_get_property_string(
2517 "org.freedesktop.systemd1",
2519 "org.freedesktop.systemd1.Unit",
2524 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2526 if (streq(state
, "masked"))
2529 r
= sd_bus_get_property_strv(
2531 "org.freedesktop.systemd1",
2533 "org.freedesktop.systemd1.Unit",
2538 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2540 STRV_FOREACH(i
, triggered_by
) {
2541 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2543 return log_error_errno(r
, "Failed to check unit: %m");
2548 if (print_warning_label
) {
2549 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2550 print_warning_label
= false;
2553 log_warning(" %s", *i
);
2559 static const struct {
2562 } unit_actions
[] = {
2563 { "start", "StartUnit" },
2564 { "stop", "StopUnit" },
2565 { "condstop", "StopUnit" },
2566 { "reload", "ReloadUnit" },
2567 { "restart", "RestartUnit" },
2568 { "try-restart", "TryRestartUnit" },
2569 { "condrestart", "TryRestartUnit" },
2570 { "reload-or-restart", "ReloadOrRestartUnit" },
2571 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2572 { "condreload", "ReloadOrTryRestartUnit" },
2573 { "force-reload", "ReloadOrTryRestartUnit" }
2576 static const char *verb_to_method(const char *verb
) {
2579 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2580 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2581 return unit_actions
[i
].method
;
2586 static const char *method_to_verb(const char *method
) {
2589 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2590 if (streq_ptr(unit_actions
[i
].method
, method
))
2591 return unit_actions
[i
].verb
;
2596 static int start_unit_one(
2601 sd_bus_error
*error
,
2602 BusWaitForJobs
*w
) {
2604 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2613 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2615 r
= sd_bus_call_method(
2617 "org.freedesktop.systemd1",
2618 "/org/freedesktop/systemd1",
2619 "org.freedesktop.systemd1.Manager",
2627 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2628 /* There's always a fallback possible for
2629 * legacy actions. */
2630 return -EADDRNOTAVAIL
;
2632 verb
= method_to_verb(method
);
2634 return log_error_errno(r
, "Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2637 r
= sd_bus_message_read(reply
, "o", &path
);
2639 return bus_log_parse_error(r
);
2641 if (need_daemon_reload(bus
, name
) > 0)
2642 warn_unit_file_changed(name
);
2645 log_debug("Adding %s to the set", path
);
2646 r
= bus_wait_for_jobs_add(w
, path
);
2654 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2655 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2662 STRV_FOREACH(name
, names
) {
2666 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2668 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2670 return log_error_errno(r
, "Failed to mangle name: %m");
2672 if (string_is_glob(t
))
2673 r
= strv_consume(&globs
, t
);
2675 r
= strv_consume(&mangled
, t
);
2680 /* Query the manager only if any of the names are a glob, since
2681 * this is fairly expensive */
2682 if (!strv_isempty(globs
)) {
2683 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2684 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2686 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2690 for (i
= 0; i
< r
; i
++)
2691 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2696 mangled
= NULL
; /* do not free */
2701 static const struct {
2705 } action_table
[_ACTION_MAX
] = {
2706 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2707 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2708 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2709 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2710 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2711 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2712 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2713 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2714 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2715 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2716 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2717 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2718 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2719 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2720 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2723 static enum action
verb_to_action(const char *verb
) {
2726 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2727 if (streq_ptr(action_table
[i
].verb
, verb
))
2730 return _ACTION_INVALID
;
2733 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2734 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2735 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2736 _cleanup_strv_free_
char **names
= NULL
;
2741 ask_password_agent_open_if_enabled();
2742 polkit_agent_open_if_enabled();
2744 r
= acquire_bus(BUS_MANAGER
, &bus
);
2748 if (arg_action
== ACTION_SYSTEMCTL
) {
2751 method
= verb_to_method(argv
[0]);
2752 action
= verb_to_action(argv
[0]);
2754 if (streq(argv
[0], "isolate")) {
2758 mode
= action_table
[action
].mode
?: arg_job_mode
;
2760 one_name
= action_table
[action
].target
;
2762 assert(arg_action
< ELEMENTSOF(action_table
));
2763 assert(action_table
[arg_action
].target
);
2765 method
= "StartUnit";
2767 mode
= action_table
[arg_action
].mode
;
2768 one_name
= action_table
[arg_action
].target
;
2772 names
= strv_new(one_name
, NULL
);
2774 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2776 return log_error_errno(r
, "Failed to expand names: %m");
2779 if (!arg_no_block
) {
2780 r
= bus_wait_for_jobs_new(bus
, &w
);
2782 return log_error_errno(r
, "Could not watch jobs: %m");
2785 STRV_FOREACH(name
, names
) {
2786 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2789 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2790 if (r
>= 0 && q
< 0)
2791 r
= translate_bus_error_to_exit_status(q
, &error
);
2794 if (!arg_no_block
) {
2797 q
= bus_wait_for_jobs(w
, arg_quiet
);
2801 /* When stopping units, warn if they can still be triggered by
2802 * another active unit (socket, path, timer) */
2803 if (!arg_quiet
&& streq(method
, "StopUnit"))
2804 STRV_FOREACH(name
, names
)
2805 check_triggering_units(bus
, *name
);
2811 static int logind_set_wall_message(void) {
2813 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2815 _cleanup_free_
char *m
= NULL
;
2818 r
= acquire_bus(BUS_FULL
, &bus
);
2822 m
= strv_join(arg_wall
, " ");
2826 r
= sd_bus_call_method(
2828 "org.freedesktop.login1",
2829 "/org/freedesktop/login1",
2830 "org.freedesktop.login1.Manager",
2839 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2845 /* Ask systemd-logind, which might grant access to unprivileged users
2846 * through PolicyKit */
2847 static int logind_reboot(enum action a
) {
2849 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2850 const char *method
, *description
;
2854 polkit_agent_open_if_enabled();
2855 (void) logind_set_wall_message();
2857 r
= acquire_bus(BUS_FULL
, &bus
);
2865 description
= "reboot system";
2868 case ACTION_POWEROFF
:
2869 method
= "PowerOff";
2870 description
= "power off system";
2873 case ACTION_SUSPEND
:
2875 description
= "suspend system";
2878 case ACTION_HIBERNATE
:
2879 method
= "Hibernate";
2880 description
= "hibernate system";
2883 case ACTION_HYBRID_SLEEP
:
2884 method
= "HybridSleep";
2885 description
= "put system into hybrid sleep";
2892 r
= sd_bus_call_method(
2894 "org.freedesktop.login1",
2895 "/org/freedesktop/login1",
2896 "org.freedesktop.login1.Manager",
2900 "b", arg_ask_password
);
2902 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2910 static int logind_check_inhibitors(enum action a
) {
2912 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2913 _cleanup_strv_free_
char **sessions
= NULL
;
2914 const char *what
, *who
, *why
, *mode
;
2921 if (arg_ignore_inhibitors
|| arg_force
> 0)
2933 r
= acquire_bus(BUS_FULL
, &bus
);
2937 r
= sd_bus_call_method(
2939 "org.freedesktop.login1",
2940 "/org/freedesktop/login1",
2941 "org.freedesktop.login1.Manager",
2947 /* If logind is not around, then there are no inhibitors... */
2950 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2952 return bus_log_parse_error(r
);
2954 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2955 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2956 _cleanup_strv_free_
char **sv
= NULL
;
2958 if (!streq(mode
, "block"))
2961 sv
= strv_split(what
, ":");
2965 if ((pid_t
) pid
< 0)
2966 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2968 if (!strv_contains(sv
,
2973 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2976 get_process_comm(pid
, &comm
);
2977 user
= uid_to_name(uid
);
2979 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2980 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2985 return bus_log_parse_error(r
);
2987 r
= sd_bus_message_exit_container(reply
);
2989 return bus_log_parse_error(r
);
2991 /* Check for current sessions */
2992 sd_get_sessions(&sessions
);
2993 STRV_FOREACH(s
, sessions
) {
2994 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2996 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2999 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3002 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3005 sd_session_get_tty(*s
, &tty
);
3006 sd_session_get_seat(*s
, &seat
);
3007 sd_session_get_service(*s
, &service
);
3008 user
= uid_to_name(uid
);
3010 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3017 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3018 action_table
[a
].verb
);
3026 static int logind_prepare_firmware_setup(void) {
3028 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3032 r
= acquire_bus(BUS_FULL
, &bus
);
3036 r
= sd_bus_call_method(
3038 "org.freedesktop.login1",
3039 "/org/freedesktop/login1",
3040 "org.freedesktop.login1.Manager",
3041 "SetRebootToFirmwareSetup",
3046 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3050 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3055 static int prepare_firmware_setup(void) {
3058 if (!arg_firmware_setup
)
3061 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3063 r
= efi_set_reboot_to_firmware(true);
3065 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3070 return logind_prepare_firmware_setup();
3073 static int set_exit_code(uint8_t code
) {
3074 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3078 r
= acquire_bus(BUS_MANAGER
, &bus
);
3082 r
= sd_bus_call_method(
3084 "org.freedesktop.systemd1",
3085 "/org/freedesktop/systemd1",
3086 "org.freedesktop.systemd1.Manager",
3092 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3097 static int start_special(int argc
, char *argv
[], void *userdata
) {
3103 a
= verb_to_action(argv
[0]);
3105 r
= logind_check_inhibitors(a
);
3109 if (arg_force
>= 2 && geteuid() != 0) {
3110 log_error("Must be root.");
3114 r
= prepare_firmware_setup();
3118 if (a
== ACTION_REBOOT
&& argc
> 1) {
3119 r
= update_reboot_param_file(argv
[1]);
3123 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3126 /* If the exit code is not given on the command line,
3127 * don't reset it to zero: just keep it as it might
3128 * have been set previously. */
3130 r
= safe_atou8(argv
[1], &code
);
3132 return log_error_errno(r
, "Invalid exit code.");
3134 r
= set_exit_code(code
);
3139 if (arg_force
>= 2 &&
3146 if (arg_force
>= 1 &&
3153 return daemon_reload(argc
, argv
, userdata
);
3155 /* First try logind, to allow authentication with polkit */
3161 ACTION_HYBRID_SLEEP
)) {
3162 r
= logind_reboot(a
);
3165 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3166 /* requested operation is not supported or already in progress */
3169 /* On all other errors, try low-level operation */
3172 return start_unit(argc
, argv
, userdata
);
3175 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3176 _cleanup_strv_free_
char **names
= NULL
;
3181 r
= acquire_bus(BUS_MANAGER
, &bus
);
3185 r
= expand_names(bus
, args
, NULL
, &names
);
3187 return log_error_errno(r
, "Failed to expand names: %m");
3189 STRV_FOREACH(name
, names
) {
3192 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3202 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3203 /* According to LSB: 3, "program is not running" */
3204 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3207 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3208 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3211 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3212 _cleanup_strv_free_
char **names
= NULL
;
3213 char *kill_who
= NULL
, **name
;
3217 polkit_agent_open_if_enabled();
3219 r
= acquire_bus(BUS_MANAGER
, &bus
);
3224 arg_kill_who
= "all";
3226 /* --fail was specified */
3227 if (streq(arg_job_mode
, "fail"))
3228 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3230 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3232 return log_error_errno(r
, "Failed to expand names: %m");
3234 STRV_FOREACH(name
, names
) {
3235 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3237 q
= sd_bus_call_method(
3239 "org.freedesktop.systemd1",
3240 "/org/freedesktop/systemd1",
3241 "org.freedesktop.systemd1.Manager",
3245 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3247 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3256 typedef struct ExecStatusInfo
{
3264 usec_t start_timestamp
;
3265 usec_t exit_timestamp
;
3270 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3273 static void exec_status_info_free(ExecStatusInfo
*i
) {
3282 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3283 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3286 int32_t code
, status
;
3292 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3294 return bus_log_parse_error(r
);
3298 r
= sd_bus_message_read(m
, "s", &path
);
3300 return bus_log_parse_error(r
);
3302 i
->path
= strdup(path
);
3306 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3308 return bus_log_parse_error(r
);
3310 r
= sd_bus_message_read(m
,
3313 &start_timestamp
, &start_timestamp_monotonic
,
3314 &exit_timestamp
, &exit_timestamp_monotonic
,
3318 return bus_log_parse_error(r
);
3321 i
->start_timestamp
= (usec_t
) start_timestamp
;
3322 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3323 i
->pid
= (pid_t
) pid
;
3327 r
= sd_bus_message_exit_container(m
);
3329 return bus_log_parse_error(r
);
3334 typedef struct UnitStatusInfo
{
3336 const char *load_state
;
3337 const char *active_state
;
3338 const char *sub_state
;
3339 const char *unit_file_state
;
3340 const char *unit_file_preset
;
3342 const char *description
;
3343 const char *following
;
3345 char **documentation
;
3347 const char *fragment_path
;
3348 const char *source_path
;
3349 const char *control_group
;
3351 char **dropin_paths
;
3353 const char *load_error
;
3356 usec_t inactive_exit_timestamp
;
3357 usec_t inactive_exit_timestamp_monotonic
;
3358 usec_t active_enter_timestamp
;
3359 usec_t active_exit_timestamp
;
3360 usec_t inactive_enter_timestamp
;
3362 bool need_daemon_reload
;
3367 const char *status_text
;
3368 const char *pid_file
;
3372 usec_t start_timestamp
;
3373 usec_t exit_timestamp
;
3375 int exit_code
, exit_status
;
3377 usec_t condition_timestamp
;
3378 bool condition_result
;
3379 bool failed_condition_trigger
;
3380 bool failed_condition_negate
;
3381 const char *failed_condition
;
3382 const char *failed_condition_parameter
;
3384 usec_t assert_timestamp
;
3386 bool failed_assert_trigger
;
3387 bool failed_assert_negate
;
3388 const char *failed_assert
;
3389 const char *failed_assert_parameter
;
3392 unsigned n_accepted
;
3393 unsigned n_connections
;
3396 /* Pairs of type, path */
3400 const char *sysfs_path
;
3402 /* Mount, Automount */
3409 uint64_t memory_current
;
3410 uint64_t memory_limit
;
3411 uint64_t cpu_usage_nsec
;
3412 uint64_t tasks_current
;
3415 LIST_HEAD(ExecStatusInfo
, exec
);
3418 static void print_status_info(
3423 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3425 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3426 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3432 /* This shows pretty information about a unit. See
3433 * print_property() for a low-level property printer */
3435 if (streq_ptr(i
->active_state
, "failed")) {
3436 active_on
= ansi_highlight_red();
3437 active_off
= ansi_normal();
3438 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3439 active_on
= ansi_highlight_green();
3440 active_off
= ansi_normal();
3442 active_on
= active_off
= "";
3444 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3446 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3447 printf(" - %s", i
->description
);
3452 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3454 if (streq_ptr(i
->load_state
, "error")) {
3455 on
= ansi_highlight_red();
3456 off
= ansi_normal();
3460 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3463 printf(" Loaded: %s%s%s (Reason: %s)\n",
3464 on
, strna(i
->load_state
), off
, i
->load_error
);
3465 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3466 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3467 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3468 else if (path
&& !isempty(i
->unit_file_state
))
3469 printf(" Loaded: %s%s%s (%s; %s)\n",
3470 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3472 printf(" Loaded: %s%s%s (%s)\n",
3473 on
, strna(i
->load_state
), off
, path
);
3475 printf(" Loaded: %s%s%s\n",
3476 on
, strna(i
->load_state
), off
);
3478 if (!strv_isempty(i
->dropin_paths
)) {
3479 _cleanup_free_
char *dir
= NULL
;
3483 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3484 if (! dir
|| last
) {
3485 printf(dir
? " " : " Drop-In: ");
3489 dir
= dirname_malloc(*dropin
);
3495 printf("%s\n %s", dir
,
3496 draw_special_char(DRAW_TREE_RIGHT
));
3499 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3501 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3505 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3507 printf(" Active: %s%s (%s)%s",
3508 active_on
, strna(i
->active_state
), ss
, active_off
);
3510 printf(" Active: %s%s%s",
3511 active_on
, strna(i
->active_state
), active_off
);
3513 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3514 printf(" (Result: %s)", i
->result
);
3516 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3517 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3518 (streq_ptr(i
->active_state
, "inactive") ||
3519 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3520 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3521 i
->active_exit_timestamp
;
3523 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3524 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3527 printf(" since %s; %s\n", s2
, s1
);
3529 printf(" since %s\n", s2
);
3533 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3534 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3535 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3537 printf("Condition: start %scondition failed%s at %s%s%s\n",
3538 ansi_highlight_yellow(), ansi_normal(),
3539 s2
, s1
? "; " : "", strempty(s1
));
3540 if (i
->failed_condition_trigger
)
3541 printf(" none of the trigger conditions were met\n");
3542 else if (i
->failed_condition
)
3543 printf(" %s=%s%s was not met\n",
3544 i
->failed_condition
,
3545 i
->failed_condition_negate
? "!" : "",
3546 i
->failed_condition_parameter
);
3549 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3550 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3551 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3553 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3554 ansi_highlight_red(), ansi_normal(),
3555 s2
, s1
? "; " : "", strempty(s1
));
3556 if (i
->failed_assert_trigger
)
3557 printf(" none of the trigger assertions were met\n");
3558 else if (i
->failed_assert
)
3559 printf(" %s=%s%s was not met\n",
3561 i
->failed_assert_negate
? "!" : "",
3562 i
->failed_assert_parameter
);
3566 printf(" Device: %s\n", i
->sysfs_path
);
3568 printf(" Where: %s\n", i
->where
);
3570 printf(" What: %s\n", i
->what
);
3572 STRV_FOREACH(t
, i
->documentation
)
3573 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3575 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3576 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3579 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3581 LIST_FOREACH(exec
, p
, i
->exec
) {
3582 _cleanup_free_
char *argv
= NULL
;
3585 /* Only show exited processes here */
3589 argv
= strv_join(p
->argv
, " ");
3590 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3592 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3594 on
= ansi_highlight_red();
3595 off
= ansi_normal();
3599 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3601 if (p
->code
== CLD_EXITED
) {
3604 printf("status=%i", p
->status
);
3606 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3611 printf("signal=%s", signal_to_string(p
->status
));
3613 printf(")%s\n", off
);
3615 if (i
->main_pid
== p
->pid
&&
3616 i
->start_timestamp
== p
->start_timestamp
&&
3617 i
->exit_timestamp
== p
->start_timestamp
)
3618 /* Let's not show this twice */
3621 if (p
->pid
== i
->control_pid
)
3625 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3626 if (i
->main_pid
> 0) {
3627 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3630 _cleanup_free_
char *comm
= NULL
;
3631 get_process_comm(i
->main_pid
, &comm
);
3633 printf(" (%s)", comm
);
3634 } else if (i
->exit_code
> 0) {
3635 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3637 if (i
->exit_code
== CLD_EXITED
) {
3640 printf("status=%i", i
->exit_status
);
3642 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3647 printf("signal=%s", signal_to_string(i
->exit_status
));
3651 if (i
->control_pid
> 0)
3655 if (i
->control_pid
> 0) {
3656 _cleanup_free_
char *c
= NULL
;
3658 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3660 get_process_comm(i
->control_pid
, &c
);
3669 printf(" Status: \"%s\"\n", i
->status_text
);
3670 if (i
->status_errno
> 0)
3671 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3673 if (i
->tasks_current
!= (uint64_t) -1) {
3674 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3676 if (i
->tasks_max
!= (uint64_t) -1)
3677 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3682 if (i
->memory_current
!= (uint64_t) -1) {
3683 char buf
[FORMAT_BYTES_MAX
];
3685 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3687 if (i
->memory_limit
!= (uint64_t) -1)
3688 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3693 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3694 char buf
[FORMAT_TIMESPAN_MAX
];
3695 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3698 if (i
->control_group
&&
3699 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3700 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3703 printf(" CGroup: %s\n", i
->control_group
);
3705 if (IN_SET(arg_transport
,
3706 BUS_TRANSPORT_LOCAL
,
3707 BUS_TRANSPORT_MACHINE
)) {
3710 static const char prefix
[] = " ";
3713 if (c
> sizeof(prefix
) - 1)
3714 c
-= sizeof(prefix
) - 1;
3718 if (i
->main_pid
> 0)
3719 extra
[k
++] = i
->main_pid
;
3721 if (i
->control_pid
> 0)
3722 extra
[k
++] = i
->control_pid
;
3724 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3728 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3729 show_journal_by_unit(
3734 i
->inactive_exit_timestamp_monotonic
,
3737 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3738 SD_JOURNAL_LOCAL_ONLY
,
3739 arg_scope
== UNIT_FILE_SYSTEM
,
3742 if (i
->need_daemon_reload
)
3743 warn_unit_file_changed(i
->id
);
3746 static void show_unit_help(UnitStatusInfo
*i
) {
3751 if (!i
->documentation
) {
3752 log_info("Documentation for %s not known.", i
->id
);
3756 STRV_FOREACH(p
, i
->documentation
)
3757 if (startswith(*p
, "man:"))
3758 show_man_page(*p
+ 4, false);
3760 log_info("Can't show: %s", *p
);
3763 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3770 switch (contents
[0]) {
3772 case SD_BUS_TYPE_STRING
: {
3775 r
= sd_bus_message_read(m
, "s", &s
);
3777 return bus_log_parse_error(r
);
3780 if (streq(name
, "Id"))
3782 else if (streq(name
, "LoadState"))
3784 else if (streq(name
, "ActiveState"))
3785 i
->active_state
= s
;
3786 else if (streq(name
, "SubState"))
3788 else if (streq(name
, "Description"))
3790 else if (streq(name
, "FragmentPath"))
3791 i
->fragment_path
= s
;
3792 else if (streq(name
, "SourcePath"))
3795 else if (streq(name
, "DefaultControlGroup")) {
3797 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3799 i
->control_group
= e
;
3802 else if (streq(name
, "ControlGroup"))
3803 i
->control_group
= s
;
3804 else if (streq(name
, "StatusText"))
3806 else if (streq(name
, "PIDFile"))
3808 else if (streq(name
, "SysFSPath"))
3810 else if (streq(name
, "Where"))
3812 else if (streq(name
, "What"))
3814 else if (streq(name
, "Following"))
3816 else if (streq(name
, "UnitFileState"))
3817 i
->unit_file_state
= s
;
3818 else if (streq(name
, "UnitFilePreset"))
3819 i
->unit_file_preset
= s
;
3820 else if (streq(name
, "Result"))
3827 case SD_BUS_TYPE_BOOLEAN
: {
3830 r
= sd_bus_message_read(m
, "b", &b
);
3832 return bus_log_parse_error(r
);
3834 if (streq(name
, "Accept"))
3836 else if (streq(name
, "NeedDaemonReload"))
3837 i
->need_daemon_reload
= b
;
3838 else if (streq(name
, "ConditionResult"))
3839 i
->condition_result
= b
;
3840 else if (streq(name
, "AssertResult"))
3841 i
->assert_result
= b
;
3846 case SD_BUS_TYPE_UINT32
: {
3849 r
= sd_bus_message_read(m
, "u", &u
);
3851 return bus_log_parse_error(r
);
3853 if (streq(name
, "MainPID")) {
3855 i
->main_pid
= (pid_t
) u
;
3858 } else if (streq(name
, "ControlPID"))
3859 i
->control_pid
= (pid_t
) u
;
3860 else if (streq(name
, "ExecMainPID")) {
3862 i
->main_pid
= (pid_t
) u
;
3863 } else if (streq(name
, "NAccepted"))
3865 else if (streq(name
, "NConnections"))
3866 i
->n_connections
= u
;
3871 case SD_BUS_TYPE_INT32
: {
3874 r
= sd_bus_message_read(m
, "i", &j
);
3876 return bus_log_parse_error(r
);
3878 if (streq(name
, "ExecMainCode"))
3879 i
->exit_code
= (int) j
;
3880 else if (streq(name
, "ExecMainStatus"))
3881 i
->exit_status
= (int) j
;
3882 else if (streq(name
, "StatusErrno"))
3883 i
->status_errno
= (int) j
;
3888 case SD_BUS_TYPE_UINT64
: {
3891 r
= sd_bus_message_read(m
, "t", &u
);
3893 return bus_log_parse_error(r
);
3895 if (streq(name
, "ExecMainStartTimestamp"))
3896 i
->start_timestamp
= (usec_t
) u
;
3897 else if (streq(name
, "ExecMainExitTimestamp"))
3898 i
->exit_timestamp
= (usec_t
) u
;
3899 else if (streq(name
, "ActiveEnterTimestamp"))
3900 i
->active_enter_timestamp
= (usec_t
) u
;
3901 else if (streq(name
, "InactiveEnterTimestamp"))
3902 i
->inactive_enter_timestamp
= (usec_t
) u
;
3903 else if (streq(name
, "InactiveExitTimestamp"))
3904 i
->inactive_exit_timestamp
= (usec_t
) u
;
3905 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3906 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3907 else if (streq(name
, "ActiveExitTimestamp"))
3908 i
->active_exit_timestamp
= (usec_t
) u
;
3909 else if (streq(name
, "ConditionTimestamp"))
3910 i
->condition_timestamp
= (usec_t
) u
;
3911 else if (streq(name
, "AssertTimestamp"))
3912 i
->assert_timestamp
= (usec_t
) u
;
3913 else if (streq(name
, "MemoryCurrent"))
3914 i
->memory_current
= u
;
3915 else if (streq(name
, "MemoryLimit"))
3916 i
->memory_limit
= u
;
3917 else if (streq(name
, "TasksCurrent"))
3918 i
->tasks_current
= u
;
3919 else if (streq(name
, "TasksMax"))
3921 else if (streq(name
, "CPUUsageNSec"))
3922 i
->cpu_usage_nsec
= u
;
3927 case SD_BUS_TYPE_ARRAY
:
3929 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3930 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3932 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3934 return bus_log_parse_error(r
);
3936 info
= new0(ExecStatusInfo
, 1);
3940 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3942 info
->name
= strdup(name
);
3946 LIST_PREPEND(exec
, i
->exec
, info
);
3948 info
= new0(ExecStatusInfo
, 1);
3954 return bus_log_parse_error(r
);
3956 r
= sd_bus_message_exit_container(m
);
3958 return bus_log_parse_error(r
);
3962 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3963 const char *type
, *path
;
3965 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3967 return bus_log_parse_error(r
);
3969 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3971 r
= strv_extend(&i
->listen
, type
);
3975 r
= strv_extend(&i
->listen
, path
);
3980 return bus_log_parse_error(r
);
3982 r
= sd_bus_message_exit_container(m
);
3984 return bus_log_parse_error(r
);
3988 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3990 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3992 return bus_log_parse_error(r
);
3994 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3996 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3998 return bus_log_parse_error(r
);
4000 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4001 const char *cond
, *param
;
4002 int trigger
, negate
;
4005 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4007 return bus_log_parse_error(r
);
4009 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4010 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4011 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4012 i
->failed_condition
= cond
;
4013 i
->failed_condition_trigger
= trigger
;
4014 i
->failed_condition_negate
= negate
;
4015 i
->failed_condition_parameter
= param
;
4019 return bus_log_parse_error(r
);
4021 r
= sd_bus_message_exit_container(m
);
4023 return bus_log_parse_error(r
);
4025 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4026 const char *cond
, *param
;
4027 int trigger
, negate
;
4030 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4032 return bus_log_parse_error(r
);
4034 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4035 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4036 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4037 i
->failed_assert
= cond
;
4038 i
->failed_assert_trigger
= trigger
;
4039 i
->failed_assert_negate
= negate
;
4040 i
->failed_assert_parameter
= param
;
4044 return bus_log_parse_error(r
);
4046 r
= sd_bus_message_exit_container(m
);
4048 return bus_log_parse_error(r
);
4055 case SD_BUS_TYPE_STRUCT_BEGIN
:
4057 if (streq(name
, "LoadError")) {
4058 const char *n
, *message
;
4060 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4062 return bus_log_parse_error(r
);
4064 if (!isempty(message
))
4065 i
->load_error
= message
;
4078 r
= sd_bus_message_skip(m
, contents
);
4080 return bus_log_parse_error(r
);
4085 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4091 /* This is a low-level property printer, see
4092 * print_status_info() for the nicer output */
4094 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4095 /* skip what we didn't read */
4096 r
= sd_bus_message_skip(m
, contents
);
4100 switch (contents
[0]) {
4102 case SD_BUS_TYPE_STRUCT_BEGIN
:
4104 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4107 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4109 return bus_log_parse_error(r
);
4112 printf("%s=%"PRIu32
"\n", name
, u
);
4114 printf("%s=\n", name
);
4118 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4121 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4123 return bus_log_parse_error(r
);
4125 if (arg_all
|| !isempty(s
))
4126 printf("%s=%s\n", name
, s
);
4130 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4131 const char *a
= NULL
, *b
= NULL
;
4133 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4135 return bus_log_parse_error(r
);
4137 if (arg_all
|| !isempty(a
) || !isempty(b
))
4138 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4141 } else if (streq_ptr(name
, "SystemCallFilter")) {
4142 _cleanup_strv_free_
char **l
= NULL
;
4145 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4147 return bus_log_parse_error(r
);
4149 r
= sd_bus_message_read(m
, "b", &whitelist
);
4151 return bus_log_parse_error(r
);
4153 r
= sd_bus_message_read_strv(m
, &l
);
4155 return bus_log_parse_error(r
);
4157 r
= sd_bus_message_exit_container(m
);
4159 return bus_log_parse_error(r
);
4161 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4165 fputs(name
, stdout
);
4171 STRV_FOREACH(i
, l
) {
4179 fputc('\n', stdout
);
4187 case SD_BUS_TYPE_ARRAY
:
4189 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4193 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4195 return bus_log_parse_error(r
);
4197 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4198 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4201 return bus_log_parse_error(r
);
4203 r
= sd_bus_message_exit_container(m
);
4205 return bus_log_parse_error(r
);
4209 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4210 const char *type
, *path
;
4212 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4214 return bus_log_parse_error(r
);
4216 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4217 printf("%s=%s\n", type
, path
);
4219 return bus_log_parse_error(r
);
4221 r
= sd_bus_message_exit_container(m
);
4223 return bus_log_parse_error(r
);
4227 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4228 const char *type
, *path
;
4230 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4232 return bus_log_parse_error(r
);
4234 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4235 printf("Listen%s=%s\n", type
, path
);
4237 return bus_log_parse_error(r
);
4239 r
= sd_bus_message_exit_container(m
);
4241 return bus_log_parse_error(r
);
4245 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4247 uint64_t value
, next_elapse
;
4249 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4251 return bus_log_parse_error(r
);
4253 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4254 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4256 printf("%s={ value=%s ; next_elapse=%s }\n",
4258 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4259 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4262 return bus_log_parse_error(r
);
4264 r
= sd_bus_message_exit_container(m
);
4266 return bus_log_parse_error(r
);
4270 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4271 ExecStatusInfo info
= {};
4273 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4275 return bus_log_parse_error(r
);
4277 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4278 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4279 _cleanup_free_
char *tt
;
4281 tt
= strv_join(info
.argv
, " ");
4283 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",
4287 yes_no(info
.ignore
),
4288 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4289 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4291 sigchld_code_to_string(info
.code
),
4293 info
.code
== CLD_EXITED
? "" : "/",
4294 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4297 strv_free(info
.argv
);
4301 r
= sd_bus_message_exit_container(m
);
4303 return bus_log_parse_error(r
);
4307 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4308 const char *path
, *rwm
;
4310 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4312 return bus_log_parse_error(r
);
4314 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4315 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4317 return bus_log_parse_error(r
);
4319 r
= sd_bus_message_exit_container(m
);
4321 return bus_log_parse_error(r
);
4325 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4329 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4331 return bus_log_parse_error(r
);
4333 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4334 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4336 return bus_log_parse_error(r
);
4338 r
= sd_bus_message_exit_container(m
);
4340 return bus_log_parse_error(r
);
4344 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4348 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4350 return bus_log_parse_error(r
);
4352 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4353 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4355 return bus_log_parse_error(r
);
4357 r
= sd_bus_message_exit_container(m
);
4359 return bus_log_parse_error(r
);
4367 r
= bus_print_property(name
, m
, arg_all
);
4369 return bus_log_parse_error(r
);
4372 r
= sd_bus_message_skip(m
, contents
);
4374 return bus_log_parse_error(r
);
4377 printf("%s=[unprintable]\n", name
);
4383 static int show_one(
4387 bool show_properties
,
4391 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4392 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4393 UnitStatusInfo info
= {
4394 .memory_current
= (uint64_t) -1,
4395 .memory_limit
= (uint64_t) -1,
4396 .cpu_usage_nsec
= (uint64_t) -1,
4397 .tasks_current
= (uint64_t) -1,
4398 .tasks_max
= (uint64_t) -1,
4406 log_debug("Showing one %s", path
);
4408 r
= sd_bus_call_method(
4410 "org.freedesktop.systemd1",
4412 "org.freedesktop.DBus.Properties",
4418 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4420 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4422 return bus_log_parse_error(r
);
4429 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4430 const char *name
, *contents
;
4432 r
= sd_bus_message_read(reply
, "s", &name
);
4434 return bus_log_parse_error(r
);
4436 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4438 return bus_log_parse_error(r
);
4440 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4442 return bus_log_parse_error(r
);
4444 if (show_properties
)
4445 r
= print_property(name
, reply
, contents
);
4447 r
= status_property(name
, reply
, &info
, contents
);
4451 r
= sd_bus_message_exit_container(reply
);
4453 return bus_log_parse_error(r
);
4455 r
= sd_bus_message_exit_container(reply
);
4457 return bus_log_parse_error(r
);
4460 return bus_log_parse_error(r
);
4462 r
= sd_bus_message_exit_container(reply
);
4464 return bus_log_parse_error(r
);
4468 if (!show_properties
) {
4469 if (streq(verb
, "help"))
4470 show_unit_help(&info
);
4472 print_status_info(&info
, ellipsized
);
4475 strv_free(info
.documentation
);
4476 strv_free(info
.dropin_paths
);
4477 strv_free(info
.listen
);
4479 if (!streq_ptr(info
.active_state
, "active") &&
4480 !streq_ptr(info
.active_state
, "reloading") &&
4481 streq(verb
, "status")) {
4482 /* According to LSB: "program not running" */
4483 /* 0: program is running or service is OK
4484 * 1: program is dead and /run PID file exists
4485 * 2: program is dead and /run/lock lock file exists
4486 * 3: program is not running
4487 * 4: program or service status is unknown
4489 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4495 while ((p
= info
.exec
)) {
4496 LIST_REMOVE(exec
, info
.exec
, p
);
4497 exec_status_info_free(p
);
4503 static int get_unit_dbus_path_by_pid(
4508 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4509 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4513 r
= sd_bus_call_method(
4515 "org.freedesktop.systemd1",
4516 "/org/freedesktop/systemd1",
4517 "org.freedesktop.systemd1.Manager",
4523 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4525 r
= sd_bus_message_read(reply
, "o", &u
);
4527 return bus_log_parse_error(r
);
4537 static int show_all(
4540 bool show_properties
,
4544 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4545 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4550 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4554 pager_open_if_enabled();
4558 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4560 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4561 _cleanup_free_
char *p
= NULL
;
4563 p
= unit_dbus_path_from_name(u
->id
);
4567 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4570 else if (r
> 0 && ret
== 0)
4577 static int show_system_status(sd_bus
*bus
) {
4578 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4579 _cleanup_free_
char *hn
= NULL
;
4580 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4581 const char *on
, *off
;
4584 hn
= gethostname_malloc();
4588 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4590 return log_error_errno(r
, "Failed to read server status: %m");
4592 if (streq_ptr(mi
.state
, "degraded")) {
4593 on
= ansi_highlight_red();
4594 off
= ansi_normal();
4595 } else if (!streq_ptr(mi
.state
, "running")) {
4596 on
= ansi_highlight_yellow();
4597 off
= ansi_normal();
4601 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4603 printf(" State: %s%s%s\n",
4604 on
, strna(mi
.state
), off
);
4606 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4607 printf(" Failed: %u units\n", mi
.n_failed_units
);
4609 printf(" Since: %s; %s\n",
4610 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4611 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4613 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4614 if (IN_SET(arg_transport
,
4615 BUS_TRANSPORT_LOCAL
,
4616 BUS_TRANSPORT_MACHINE
)) {
4617 static const char prefix
[] = " ";
4621 if (c
> sizeof(prefix
) - 1)
4622 c
-= sizeof(prefix
) - 1;
4626 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4632 static int show(int argc
, char *argv
[], void *userdata
) {
4633 bool show_properties
, show_status
, show_help
, new_line
= false;
4634 bool ellipsized
= false;
4640 show_properties
= streq(argv
[0], "show");
4641 show_status
= streq(argv
[0], "status");
4642 show_help
= streq(argv
[0], "help");
4644 if (show_help
&& argc
<= 1) {
4645 log_error("This command expects one or more unit names. Did you mean --help?");
4649 if (show_properties
)
4650 pager_open_if_enabled();
4653 /* Increase max number of open files to 16K if we can, we
4654 * might needs this when browsing journal files, which might
4655 * be split up into many files. */
4656 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4658 r
= acquire_bus(BUS_MANAGER
, &bus
);
4662 /* If no argument is specified inspect the manager itself */
4663 if (show_properties
&& argc
<= 1)
4664 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4666 if (show_status
&& argc
<= 1) {
4668 pager_open_if_enabled();
4669 show_system_status(bus
);
4673 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4675 _cleanup_free_
char **patterns
= NULL
;
4678 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4679 _cleanup_free_
char *unit
= NULL
;
4682 if (safe_atou32(*name
, &id
) < 0) {
4683 if (strv_push(&patterns
, *name
) < 0)
4687 } else if (show_properties
) {
4688 /* Interpret as job id */
4689 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4693 /* Interpret as PID */
4694 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4701 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4704 else if (r
> 0 && ret
== 0)
4708 if (!strv_isempty(patterns
)) {
4709 _cleanup_strv_free_
char **names
= NULL
;
4711 r
= expand_names(bus
, patterns
, NULL
, &names
);
4713 return log_error_errno(r
, "Failed to expand names: %m");
4715 STRV_FOREACH(name
, names
) {
4716 _cleanup_free_
char *unit
;
4718 unit
= unit_dbus_path_from_name(*name
);
4722 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4725 else if (r
> 0 && ret
== 0)
4731 if (ellipsized
&& !arg_quiet
)
4732 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4737 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4741 assert(user_runtime
);
4744 if (arg_scope
== UNIT_FILE_USER
) {
4745 r
= user_config_home(user_home
);
4747 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4749 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4751 r
= user_runtime_dir(user_runtime
);
4753 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4755 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4758 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4760 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4765 static int cat_file(const char *filename
, bool newline
) {
4766 _cleanup_close_
int fd
;
4768 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4772 printf("%s%s# %s%s\n",
4773 newline
? "\n" : "",
4774 ansi_highlight_blue(),
4779 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4782 static int cat(int argc
, char *argv
[], void *userdata
) {
4783 _cleanup_free_
char *user_home
= NULL
;
4784 _cleanup_free_
char *user_runtime
= NULL
;
4785 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4786 _cleanup_strv_free_
char **names
= NULL
;
4792 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4793 log_error("Cannot remotely cat units.");
4797 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4801 r
= acquire_bus(BUS_MANAGER
, &bus
);
4805 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4807 return log_error_errno(r
, "Failed to expand names: %m");
4809 pager_open_if_enabled();
4811 STRV_FOREACH(name
, names
) {
4812 _cleanup_free_
char *fragment_path
= NULL
;
4813 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4816 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4827 if (fragment_path
) {
4828 r
= cat_file(fragment_path
, false);
4830 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4833 STRV_FOREACH(path
, dropin_paths
) {
4834 r
= cat_file(*path
, path
== dropin_paths
);
4836 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4843 static int set_property(int argc
, char *argv
[], void *userdata
) {
4844 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4845 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4846 _cleanup_free_
char *n
= NULL
;
4851 polkit_agent_open_if_enabled();
4853 r
= acquire_bus(BUS_MANAGER
, &bus
);
4857 r
= sd_bus_message_new_method_call(
4860 "org.freedesktop.systemd1",
4861 "/org/freedesktop/systemd1",
4862 "org.freedesktop.systemd1.Manager",
4863 "SetUnitProperties");
4865 return bus_log_create_error(r
);
4867 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4869 return log_error_errno(r
, "Failed to mangle unit name: %m");
4871 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4873 return bus_log_create_error(r
);
4875 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4877 return bus_log_create_error(r
);
4879 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4880 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4882 return bus_log_create_error(r
);
4884 r
= bus_append_unit_property_assignment(m
, *i
);
4888 r
= sd_bus_message_close_container(m
);
4890 return bus_log_create_error(r
);
4893 r
= sd_bus_message_close_container(m
);
4895 return bus_log_create_error(r
);
4897 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4899 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4904 static int snapshot(int argc
, char *argv
[], void *userdata
) {
4905 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4906 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4907 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4912 polkit_agent_open_if_enabled();
4915 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4917 return log_error_errno(r
, "Failed to generate unit name: %m");
4924 r
= acquire_bus(BUS_MANAGER
, &bus
);
4928 r
= sd_bus_call_method(
4930 "org.freedesktop.systemd1",
4931 "/org/freedesktop/systemd1",
4932 "org.freedesktop.systemd1.Manager",
4938 return log_error_errno(r
, "Failed to create snapshot: %s", bus_error_message(&error
, r
));
4940 r
= sd_bus_message_read(reply
, "o", &path
);
4942 return bus_log_parse_error(r
);
4944 r
= sd_bus_get_property_string(
4946 "org.freedesktop.systemd1",
4948 "org.freedesktop.systemd1.Unit",
4953 return log_error_errno(r
, "Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4961 static int delete_snapshot(int argc
, char *argv
[], void *userdata
) {
4962 _cleanup_strv_free_
char **names
= NULL
;
4967 polkit_agent_open_if_enabled();
4969 r
= acquire_bus(BUS_MANAGER
, &bus
);
4973 r
= expand_names(bus
, strv_skip(argv
, 1), ".snapshot", &names
);
4975 return log_error_errno(r
, "Failed to expand names: %m");
4977 STRV_FOREACH(name
, names
) {
4978 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4981 q
= sd_bus_call_method(
4983 "org.freedesktop.systemd1",
4984 "/org/freedesktop/systemd1",
4985 "org.freedesktop.systemd1.Manager",
4991 log_error_errno(q
, "Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
5000 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5001 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5006 polkit_agent_open_if_enabled();
5008 r
= acquire_bus(BUS_MANAGER
, &bus
);
5012 if (arg_action
== ACTION_RELOAD
)
5014 else if (arg_action
== ACTION_REEXEC
)
5015 method
= "Reexecute";
5017 assert(arg_action
== ACTION_SYSTEMCTL
);
5020 streq(argv
[0], "clear-jobs") ||
5021 streq(argv
[0], "cancel") ? "ClearJobs" :
5022 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5023 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5024 streq(argv
[0], "halt") ? "Halt" :
5025 streq(argv
[0], "poweroff") ? "PowerOff" :
5026 streq(argv
[0], "reboot") ? "Reboot" :
5027 streq(argv
[0], "kexec") ? "KExec" :
5028 streq(argv
[0], "exit") ? "Exit" :
5029 /* "daemon-reload" */ "Reload";
5032 r
= sd_bus_call_method(
5034 "org.freedesktop.systemd1",
5035 "/org/freedesktop/systemd1",
5036 "org.freedesktop.systemd1.Manager",
5041 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
5042 /* There's always a fallback possible for
5043 * legacy actions. */
5045 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
5046 /* On reexecution, we expect a disconnect, not a
5050 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5052 return r
< 0 ? r
: 0;
5055 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5056 _cleanup_strv_free_
char **names
= NULL
;
5062 return daemon_reload(argc
, argv
, userdata
);
5064 polkit_agent_open_if_enabled();
5066 r
= acquire_bus(BUS_MANAGER
, &bus
);
5070 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5072 return log_error_errno(r
, "Failed to expand names: %m");
5074 STRV_FOREACH(name
, names
) {
5075 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5077 q
= sd_bus_call_method(
5079 "org.freedesktop.systemd1",
5080 "/org/freedesktop/systemd1",
5081 "org.freedesktop.systemd1.Manager",
5087 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5096 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5097 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5098 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5103 pager_open_if_enabled();
5105 r
= acquire_bus(BUS_MANAGER
, &bus
);
5109 r
= sd_bus_get_property(
5111 "org.freedesktop.systemd1",
5112 "/org/freedesktop/systemd1",
5113 "org.freedesktop.systemd1.Manager",
5119 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5121 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5123 return bus_log_parse_error(r
);
5125 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5128 return bus_log_parse_error(r
);
5130 r
= sd_bus_message_exit_container(reply
);
5132 return bus_log_parse_error(r
);
5137 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5138 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5139 _cleanup_free_
char *cmdline_init
= NULL
;
5140 const char *root
, *init
;
5144 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5145 log_error("Cannot switch root remotely.");
5149 if (argc
< 2 || argc
> 3) {
5150 log_error("Wrong number of arguments.");
5159 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5160 "init", &cmdline_init
,
5163 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5165 init
= cmdline_init
;
5172 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5174 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5175 root_init_path
= strjoina(root
, "/", init
);
5177 /* If the passed init is actually the same as the
5178 * systemd binary, then let's suppress it. */
5179 if (files_same(root_init_path
, root_systemd_path
) > 0)
5183 r
= acquire_bus(BUS_MANAGER
, &bus
);
5187 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5189 r
= sd_bus_call_method(
5191 "org.freedesktop.systemd1",
5192 "/org/freedesktop/systemd1",
5193 "org.freedesktop.systemd1.Manager",
5199 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5204 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5205 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5206 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5214 polkit_agent_open_if_enabled();
5216 r
= acquire_bus(BUS_MANAGER
, &bus
);
5220 method
= streq(argv
[0], "set-environment")
5222 : "UnsetEnvironment";
5224 r
= sd_bus_message_new_method_call(
5227 "org.freedesktop.systemd1",
5228 "/org/freedesktop/systemd1",
5229 "org.freedesktop.systemd1.Manager",
5232 return bus_log_create_error(r
);
5234 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5236 return bus_log_create_error(r
);
5238 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5240 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5245 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5246 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5247 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5251 polkit_agent_open_if_enabled();
5253 r
= acquire_bus(BUS_MANAGER
, &bus
);
5257 r
= sd_bus_message_new_method_call(
5260 "org.freedesktop.systemd1",
5261 "/org/freedesktop/systemd1",
5262 "org.freedesktop.systemd1.Manager",
5265 return bus_log_create_error(r
);
5268 r
= sd_bus_message_append_strv(m
, environ
);
5272 r
= sd_bus_message_open_container(m
, 'a', "s");
5274 return bus_log_create_error(r
);
5276 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5278 if (!env_name_is_valid(*a
)) {
5279 log_error("Not a valid environment variable name: %s", *a
);
5283 STRV_FOREACH(b
, environ
) {
5286 eq
= startswith(*b
, *a
);
5287 if (eq
&& *eq
== '=') {
5289 r
= sd_bus_message_append(m
, "s", *b
);
5291 return bus_log_create_error(r
);
5298 r
= sd_bus_message_close_container(m
);
5301 return bus_log_create_error(r
);
5303 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5305 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5310 static int enable_sysv_units(const char *verb
, char **args
) {
5313 #if defined(HAVE_SYSV_COMPAT)
5315 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5317 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5320 if (!STR_IN_SET(verb
,
5326 /* Processes all SysV units, and reshuffles the array so that
5327 * afterwards only the native units remain */
5329 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5336 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5337 bool found_native
= false, found_sysv
;
5339 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5347 if (!endswith(name
, ".service"))
5350 if (path_is_absolute(name
))
5353 STRV_FOREACH(k
, paths
.unit_path
) {
5354 _cleanup_free_
char *path
= NULL
;
5356 path
= path_join(arg_root
, *k
, name
);
5360 found_native
= access(path
, F_OK
) >= 0;
5365 /* If we have both a native unit and a SysV script,
5366 * enable/disable them both (below); for is-enabled, prefer the
5368 if (found_native
&& streq(verb
, "is-enabled"))
5371 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5375 p
[strlen(p
) - strlen(".service")] = 0;
5376 found_sysv
= access(p
, F_OK
) >= 0;
5381 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5383 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5385 if (!isempty(arg_root
))
5386 argv
[c
++] = q
= strappend("--root=", arg_root
);
5389 argv
[c
++] = basename(p
);
5392 l
= strv_join((char**)argv
, " ");
5396 log_info("Executing %s", l
);
5400 return log_error_errno(errno
, "Failed to fork: %m");
5401 else if (pid
== 0) {
5404 (void) reset_all_signal_handlers();
5405 (void) reset_signal_mask();
5407 execv(argv
[0], (char**) argv
);
5408 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5409 _exit(EXIT_FAILURE
);
5412 j
= wait_for_terminate(pid
, &status
);
5414 log_error_errno(j
, "Failed to wait for child: %m");
5418 if (status
.si_code
== CLD_EXITED
) {
5419 if (streq(verb
, "is-enabled")) {
5420 if (status
.si_status
== 0) {
5429 } else if (status
.si_status
!= 0)
5437 /* Remove this entry, so that we don't try enabling it as native unit */
5440 assert(args
[f
] == name
);
5441 strv_remove(args
, name
);
5448 static int mangle_names(char **original_names
, char ***mangled_names
) {
5449 char **i
, **l
, **name
;
5452 l
= i
= new(char*, strv_length(original_names
) + 1);
5456 STRV_FOREACH(name
, original_names
) {
5458 /* When enabling units qualified path names are OK,
5459 * too, hence allow them explicitly. */
5461 if (is_path(*name
)) {
5468 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5471 return log_error_errno(r
, "Failed to mangle unit name: %m");
5484 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5485 _cleanup_strv_free_
char **names
= NULL
;
5486 const char *verb
= argv
[0];
5487 UnitFileChange
*changes
= NULL
;
5488 unsigned n_changes
= 0;
5489 int carries_install_info
= -1;
5495 r
= mangle_names(strv_skip(argv
, 1), &names
);
5499 r
= enable_sysv_units(verb
, names
);
5503 /* If the operation was fully executed by the SysV compat,
5504 * let's finish early */
5505 if (strv_isempty(names
))
5508 if (install_client_side()) {
5509 if (streq(verb
, "enable")) {
5510 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5511 carries_install_info
= r
;
5512 } else if (streq(verb
, "disable"))
5513 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5514 else if (streq(verb
, "reenable")) {
5515 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5516 carries_install_info
= r
;
5517 } else if (streq(verb
, "link"))
5518 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5519 else if (streq(verb
, "preset")) {
5520 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5521 carries_install_info
= r
;
5522 } else if (streq(verb
, "mask"))
5523 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5524 else if (streq(verb
, "unmask"))
5525 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5527 assert_not_reached("Unknown verb");
5530 log_error_errno(r
, "Operation failed: %m");
5535 dump_unit_file_changes(changes
, n_changes
);
5539 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5540 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5541 int expect_carries_install_info
= false;
5542 bool send_force
= true, send_preset_mode
= false;
5546 polkit_agent_open_if_enabled();
5548 r
= acquire_bus(BUS_MANAGER
, &bus
);
5552 if (streq(verb
, "enable")) {
5553 method
= "EnableUnitFiles";
5554 expect_carries_install_info
= true;
5555 } else if (streq(verb
, "disable")) {
5556 method
= "DisableUnitFiles";
5558 } else if (streq(verb
, "reenable")) {
5559 method
= "ReenableUnitFiles";
5560 expect_carries_install_info
= true;
5561 } else if (streq(verb
, "link"))
5562 method
= "LinkUnitFiles";
5563 else if (streq(verb
, "preset")) {
5565 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5566 method
= "PresetUnitFilesWithMode";
5567 send_preset_mode
= true;
5569 method
= "PresetUnitFiles";
5571 expect_carries_install_info
= true;
5572 } else if (streq(verb
, "mask"))
5573 method
= "MaskUnitFiles";
5574 else if (streq(verb
, "unmask")) {
5575 method
= "UnmaskUnitFiles";
5578 assert_not_reached("Unknown verb");
5580 r
= sd_bus_message_new_method_call(
5583 "org.freedesktop.systemd1",
5584 "/org/freedesktop/systemd1",
5585 "org.freedesktop.systemd1.Manager",
5588 return bus_log_create_error(r
);
5590 r
= sd_bus_message_append_strv(m
, names
);
5592 return bus_log_create_error(r
);
5594 if (send_preset_mode
) {
5595 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5597 return bus_log_create_error(r
);
5600 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5602 return bus_log_create_error(r
);
5605 r
= sd_bus_message_append(m
, "b", arg_force
);
5607 return bus_log_create_error(r
);
5610 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5612 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5614 if (expect_carries_install_info
) {
5615 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5617 return bus_log_parse_error(r
);
5620 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5624 /* Try to reload if enabled */
5626 r
= daemon_reload(argc
, argv
, userdata
);
5631 if (carries_install_info
== 0)
5632 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5633 "using systemctl.\n"
5634 "Possible reasons for having this kind of units are:\n"
5635 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5636 " .wants/ or .requires/ directory.\n"
5637 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5638 " a requirement dependency on it.\n"
5639 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5640 " D-Bus, udev, scripted systemctl call, ...).\n");
5642 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5643 char *new_args
[n_changes
+ 2];
5647 r
= acquire_bus(BUS_MANAGER
, &bus
);
5651 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5652 for (i
= 0; i
< n_changes
; i
++)
5653 new_args
[i
+ 1] = basename(changes
[i
].path
);
5654 new_args
[i
+ 1] = NULL
;
5656 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5660 unit_file_changes_free(changes
, n_changes
);
5665 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5666 _cleanup_strv_free_
char **names
= NULL
;
5667 _cleanup_free_
char *target
= NULL
;
5668 const char *verb
= argv
[0];
5675 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5677 return log_error_errno(r
, "Failed to mangle unit name: %m");
5679 r
= mangle_names(strv_skip(argv
, 2), &names
);
5683 if (streq(verb
, "add-wants"))
5685 else if (streq(verb
, "add-requires"))
5686 dep
= UNIT_REQUIRES
;
5688 assert_not_reached("Unknown verb");
5690 if (install_client_side()) {
5691 UnitFileChange
*changes
= NULL
;
5692 unsigned n_changes
= 0;
5694 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5697 return log_error_errno(r
, "Can't add dependency: %m");
5700 dump_unit_file_changes(changes
, n_changes
);
5702 unit_file_changes_free(changes
, n_changes
);
5705 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5706 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5709 polkit_agent_open_if_enabled();
5711 r
= acquire_bus(BUS_MANAGER
, &bus
);
5715 r
= sd_bus_message_new_method_call(
5718 "org.freedesktop.systemd1",
5719 "/org/freedesktop/systemd1",
5720 "org.freedesktop.systemd1.Manager",
5721 "AddDependencyUnitFiles");
5723 return bus_log_create_error(r
);
5725 r
= sd_bus_message_append_strv(m
, names
);
5727 return bus_log_create_error(r
);
5729 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5731 return bus_log_create_error(r
);
5733 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5735 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5737 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5742 r
= daemon_reload(argc
, argv
, userdata
);
5750 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5751 UnitFileChange
*changes
= NULL
;
5752 unsigned n_changes
= 0;
5755 if (install_client_side()) {
5757 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5759 log_error_errno(r
, "Operation failed: %m");
5764 dump_unit_file_changes(changes
, n_changes
);
5769 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5770 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5773 polkit_agent_open_if_enabled();
5775 r
= acquire_bus(BUS_MANAGER
, &bus
);
5779 r
= sd_bus_call_method(
5781 "org.freedesktop.systemd1",
5782 "/org/freedesktop/systemd1",
5783 "org.freedesktop.systemd1.Manager",
5784 "PresetAllUnitFiles",
5788 unit_file_preset_mode_to_string(arg_preset_mode
),
5792 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5794 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5799 r
= daemon_reload(argc
, argv
, userdata
);
5805 unit_file_changes_free(changes
, n_changes
);
5810 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5812 _cleanup_strv_free_
char **names
= NULL
;
5817 r
= mangle_names(strv_skip(argv
, 1), &names
);
5821 r
= enable_sysv_units(argv
[0], names
);
5827 if (install_client_side()) {
5829 STRV_FOREACH(name
, names
) {
5830 UnitFileState state
;
5832 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5834 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5838 UNIT_FILE_ENABLED_RUNTIME
,
5840 UNIT_FILE_INDIRECT
))
5844 puts(unit_file_state_to_string(state
));
5848 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5851 r
= acquire_bus(BUS_MANAGER
, &bus
);
5855 STRV_FOREACH(name
, names
) {
5856 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5859 r
= sd_bus_call_method(
5861 "org.freedesktop.systemd1",
5862 "/org/freedesktop/systemd1",
5863 "org.freedesktop.systemd1.Manager",
5869 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5871 r
= sd_bus_message_read(reply
, "s", &s
);
5873 return bus_log_parse_error(r
);
5875 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5886 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5887 _cleanup_free_
char *state
= NULL
;
5891 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5894 return EXIT_FAILURE
;
5897 r
= acquire_bus(BUS_MANAGER
, &bus
);
5901 r
= sd_bus_get_property_string(
5903 "org.freedesktop.systemd1",
5904 "/org/freedesktop/systemd1",
5905 "org.freedesktop.systemd1.Manager",
5918 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5921 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5922 _cleanup_free_
char *t
= NULL
;
5926 assert(original_path
);
5929 r
= tempfn_random(new_path
, NULL
, &t
);
5931 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5933 r
= mkdir_parents(new_path
, 0755);
5935 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5937 r
= copy_file(original_path
, t
, 0, 0644, 0);
5942 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5945 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5953 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5954 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5959 switch (arg_scope
) {
5960 case UNIT_FILE_SYSTEM
:
5961 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5963 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5965 case UNIT_FILE_GLOBAL
:
5966 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5968 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5970 case UNIT_FILE_USER
:
5972 assert(user_runtime
);
5974 path
= path_join(arg_root
, user_home
, name
);
5976 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5979 run
= path_join(arg_root
, user_runtime
, name
);
5983 assert_not_reached("Invalid scope");
5985 if (!path
|| (arg_runtime
&& !run
))
5989 if (access(path
, F_OK
) >= 0) {
5990 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5994 if (path2
&& access(path2
, F_OK
) >= 0) {
5995 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
6009 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
) {
6010 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6014 assert(ret_new_path
);
6015 assert(ret_tmp_path
);
6017 ending
= strjoina(unit_name
, ".d/override.conf");
6018 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
6022 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6028 *ret_new_path
= tmp_new_path
;
6029 *ret_tmp_path
= tmp_tmp_path
;
6034 static int unit_file_create_copy(
6035 const char *unit_name
,
6036 const char *fragment_path
,
6037 const char *user_home
,
6038 const char *user_runtime
,
6039 char **ret_new_path
,
6040 char **ret_tmp_path
) {
6042 char *tmp_new_path
, *tmp_tmp_path
;
6045 assert(fragment_path
);
6047 assert(ret_new_path
);
6048 assert(ret_tmp_path
);
6050 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
6054 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6057 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6062 if (response
!= 'y') {
6063 log_warning("%s ignored", unit_name
);
6069 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6071 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6076 *ret_new_path
= tmp_new_path
;
6077 *ret_tmp_path
= tmp_tmp_path
;
6082 static int run_editor(char **paths
) {
6090 return log_error_errno(errno
, "Failed to fork: %m");
6094 char *editor
, **editor_args
= NULL
;
6095 char **tmp_path
, **original_path
, *p
;
6096 unsigned n_editor_args
= 0, i
= 1;
6099 (void) reset_all_signal_handlers();
6100 (void) reset_signal_mask();
6102 argc
= strv_length(paths
)/2 + 1;
6104 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6105 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6106 * we try to execute well known editors
6108 editor
= getenv("SYSTEMD_EDITOR");
6110 editor
= getenv("EDITOR");
6112 editor
= getenv("VISUAL");
6114 if (!isempty(editor
)) {
6115 editor_args
= strv_split(editor
, WHITESPACE
);
6118 _exit(EXIT_FAILURE
);
6120 n_editor_args
= strv_length(editor_args
);
6121 argc
+= n_editor_args
- 1;
6123 args
= newa(const char*, argc
+ 1);
6125 if (n_editor_args
> 0) {
6126 args
[0] = editor_args
[0];
6127 for (; i
< n_editor_args
; i
++)
6128 args
[i
] = editor_args
[i
];
6131 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6132 args
[i
] = *tmp_path
;
6137 if (n_editor_args
> 0)
6138 execvp(args
[0], (char* const*) args
);
6140 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6142 execvp(p
, (char* const*) args
);
6143 /* We do not fail if the editor doesn't exist
6144 * because we want to try each one of them before
6147 if (errno
!= ENOENT
) {
6148 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6149 _exit(EXIT_FAILURE
);
6153 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6154 _exit(EXIT_FAILURE
);
6157 r
= wait_for_terminate_and_warn("editor", pid
, true);
6159 return log_error_errno(r
, "Failed to wait for child: %m");
6164 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6165 _cleanup_free_
char *user_home
= NULL
;
6166 _cleanup_free_
char *user_runtime
= NULL
;
6167 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6174 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6178 STRV_FOREACH(name
, names
) {
6179 _cleanup_free_
char *path
= NULL
;
6180 char *new_path
, *tmp_path
;
6182 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6188 // FIXME: support units with path==NULL (no FragmentPath)
6189 log_error("No fragment exists for %s.", *name
);
6194 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6196 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6200 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6208 static int edit(int argc
, char *argv
[], void *userdata
) {
6209 _cleanup_strv_free_
char **names
= NULL
;
6210 _cleanup_strv_free_
char **paths
= NULL
;
6211 char **original
, **tmp
;
6216 log_error("Cannot edit units if not on a tty.");
6220 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6221 log_error("Cannot edit units remotely.");
6225 r
= acquire_bus(BUS_MANAGER
, &bus
);
6229 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6231 return log_error_errno(r
, "Failed to expand names: %m");
6233 r
= find_paths_to_edit(bus
, names
, &paths
);
6237 if (strv_isempty(paths
))
6240 r
= run_editor(paths
);
6244 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6245 /* If the temporary file is empty we ignore it. It's
6246 * useful if the user wants to cancel its modification
6248 if (null_or_empty_path(*tmp
)) {
6249 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6253 r
= rename(*tmp
, *original
);
6255 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6262 if (!arg_no_reload
&& !install_client_side())
6263 r
= daemon_reload(argc
, argv
, userdata
);
6266 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6267 (void) unlink(*tmp
);
6272 static void systemctl_help(void) {
6274 pager_open_if_enabled();
6276 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6277 "Query or send control commands to the systemd manager.\n\n"
6278 " -h --help Show this help\n"
6279 " --version Show package version\n"
6280 " --system Connect to system manager\n"
6281 " --user Connect to user service manager\n"
6282 " -H --host=[USER@]HOST\n"
6283 " Operate on remote host\n"
6284 " -M --machine=CONTAINER\n"
6285 " Operate on local container\n"
6286 " -t --type=TYPE List units of a particular type\n"
6287 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6288 " -p --property=NAME Show only properties by this name\n"
6289 " -a --all Show all loaded units/properties, including dead/empty\n"
6290 " ones. To list all units installed on the system, use\n"
6291 " the 'list-unit-files' command instead.\n"
6292 " -l --full Don't ellipsize unit names on output\n"
6293 " -r --recursive Show unit list of host and local containers\n"
6294 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6295 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6296 " queueing a new job\n"
6297 " --show-types When showing sockets, explicitly show their type\n"
6298 " -i --ignore-inhibitors\n"
6299 " When shutting down or sleeping, ignore inhibitors\n"
6300 " --kill-who=WHO Who to send signal to\n"
6301 " -s --signal=SIGNAL Which signal to send\n"
6302 " --now Start or stop unit in addition to enabling or disabling it\n"
6303 " -q --quiet Suppress output\n"
6304 " --no-block Do not wait until operation finished\n"
6305 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6306 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6307 " --no-legend Do not print a legend (column headers and hints)\n"
6308 " --no-pager Do not pipe output into a pager\n"
6309 " --no-ask-password\n"
6310 " Do not ask for system passwords\n"
6311 " --global Enable/disable unit files globally\n"
6312 " --runtime Enable unit files only temporarily until next reboot\n"
6313 " -f --force When enabling unit files, override existing symlinks\n"
6314 " When shutting down, execute action immediately\n"
6315 " --preset-mode= Apply only enable, only disable, or all presets\n"
6316 " --root=PATH Enable unit files in the specified root directory\n"
6317 " -n --lines=INTEGER Number of journal entries to show\n"
6318 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6319 " short-precise, short-monotonic, verbose,\n"
6320 " export, json, json-pretty, json-sse, cat)\n"
6321 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6322 " --plain Print unit dependencies as a list instead of a tree\n\n"
6324 " list-units [PATTERN...] List loaded units\n"
6325 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6326 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6327 " start NAME... Start (activate) one or more units\n"
6328 " stop NAME... Stop (deactivate) one or more units\n"
6329 " reload NAME... Reload one or more units\n"
6330 " restart NAME... Start or restart one or more units\n"
6331 " try-restart NAME... Restart one or more units if active\n"
6332 " reload-or-restart NAME... Reload one or more units if possible,\n"
6333 " otherwise start or restart\n"
6334 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6335 " otherwise restart if active\n"
6336 " isolate NAME Start one unit and stop all others\n"
6337 " kill NAME... Send signal to processes of a unit\n"
6338 " is-active PATTERN... Check whether units are active\n"
6339 " is-failed PATTERN... Check whether units are failed\n"
6340 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6341 " show [PATTERN...|JOB...] Show properties of one or more\n"
6342 " units/jobs or the manager\n"
6343 " cat PATTERN... Show files and drop-ins of one or more units\n"
6344 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6345 " help PATTERN...|PID... Show manual for one or more units\n"
6346 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6348 " list-dependencies [NAME] Recursively show units which are required\n"
6349 " or wanted by this unit or by which this\n"
6350 " unit is required or wanted\n\n"
6351 "Unit File Commands:\n"
6352 " list-unit-files [PATTERN...] List installed unit files\n"
6353 " enable NAME... Enable one or more unit files\n"
6354 " disable NAME... Disable one or more unit files\n"
6355 " reenable NAME... Reenable one or more unit files\n"
6356 " preset NAME... Enable/disable one or more unit files\n"
6357 " based on preset configuration\n"
6358 " preset-all Enable/disable all unit files based on\n"
6359 " preset configuration\n"
6360 " is-enabled NAME... Check whether unit files are enabled\n"
6361 " mask NAME... Mask one or more units\n"
6362 " unmask NAME... Unmask one or more units\n"
6363 " link PATH... Link one or more units files into\n"
6364 " the search path\n"
6365 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6366 " on specified one or more units\n"
6367 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6368 " on specified one or more units\n"
6369 " edit NAME... Edit one or more unit files\n"
6370 " get-default Get the name of the default target\n"
6371 " set-default NAME Set the default target\n\n"
6372 "Machine Commands:\n"
6373 " list-machines [PATTERN...] List local containers and host\n\n"
6375 " list-jobs [PATTERN...] List jobs\n"
6376 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6377 "Snapshot Commands:\n"
6378 " snapshot [NAME] Create a snapshot\n"
6379 " delete NAME... Remove one or more snapshots\n\n"
6380 "Environment Commands:\n"
6381 " show-environment Dump environment\n"
6382 " set-environment NAME=VALUE... Set one or more environment variables\n"
6383 " unset-environment NAME... Unset one or more environment variables\n"
6384 " import-environment [NAME...] Import all or some environment variables\n\n"
6385 "Manager Lifecycle Commands:\n"
6386 " daemon-reload Reload systemd manager configuration\n"
6387 " daemon-reexec Reexecute systemd manager\n\n"
6388 "System Commands:\n"
6389 " is-system-running Check whether system is fully running\n"
6390 " default Enter system default mode\n"
6391 " rescue Enter system rescue mode\n"
6392 " emergency Enter system emergency mode\n"
6393 " halt Shut down and halt the system\n"
6394 " poweroff Shut down and power-off the system\n"
6395 " reboot [ARG] Shut down and reboot the system\n"
6396 " kexec Shut down and reboot the system with kexec\n"
6397 " exit [EXIT_CODE] Request user instance or container exit\n"
6398 " switch-root ROOT [INIT] Change to a different root file system\n"
6399 " suspend Suspend the system\n"
6400 " hibernate Hibernate the system\n"
6401 " hybrid-sleep Hibernate and suspend the system\n",
6402 program_invocation_short_name
);
6405 static void halt_help(void) {
6406 printf("%s [OPTIONS...]%s\n\n"
6407 "%s the system.\n\n"
6408 " --help Show this help\n"
6409 " --halt Halt the machine\n"
6410 " -p --poweroff Switch off the machine\n"
6411 " --reboot Reboot the machine\n"
6412 " -f --force Force immediate halt/power-off/reboot\n"
6413 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6414 " -d --no-wtmp Don't write wtmp record\n"
6415 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6416 program_invocation_short_name
,
6417 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6418 arg_action
== ACTION_REBOOT
? "Reboot" :
6419 arg_action
== ACTION_POWEROFF
? "Power off" :
6423 static void shutdown_help(void) {
6424 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6425 "Shut down the system.\n\n"
6426 " --help Show this help\n"
6427 " -H --halt Halt the machine\n"
6428 " -P --poweroff Power-off the machine\n"
6429 " -r --reboot Reboot the machine\n"
6430 " -h Equivalent to --poweroff, overridden by --halt\n"
6431 " -k Don't halt/power-off/reboot, just send warnings\n"
6432 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6433 " -c Cancel a pending shutdown\n",
6434 program_invocation_short_name
);
6437 static void telinit_help(void) {
6438 printf("%s [OPTIONS...] {COMMAND}\n\n"
6439 "Send control commands to the init daemon.\n\n"
6440 " --help Show this help\n"
6441 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6443 " 0 Power-off the machine\n"
6444 " 6 Reboot the machine\n"
6445 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6446 " 1, s, S Enter rescue mode\n"
6447 " q, Q Reload init daemon configuration\n"
6448 " u, U Reexecute init daemon\n",
6449 program_invocation_short_name
);
6452 static void runlevel_help(void) {
6453 printf("%s [OPTIONS...]\n\n"
6454 "Prints the previous and current runlevel of the init system.\n\n"
6455 " --help Show this help\n",
6456 program_invocation_short_name
);
6459 static void help_types(void) {
6463 puts("Available unit types:");
6464 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6465 puts(unit_type_to_string(i
));
6468 static void help_states(void) {
6472 puts("Available unit load states:");
6473 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6474 puts(unit_load_state_to_string(i
));
6477 puts("\nAvailable unit active states:");
6478 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6479 puts(unit_active_state_to_string(i
));
6482 puts("\nAvailable automount unit substates:");
6483 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6484 puts(automount_state_to_string(i
));
6487 puts("\nAvailable busname unit substates:");
6488 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6489 puts(busname_state_to_string(i
));
6492 puts("\nAvailable device unit substates:");
6493 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6494 puts(device_state_to_string(i
));
6497 puts("\nAvailable mount unit substates:");
6498 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6499 puts(mount_state_to_string(i
));
6502 puts("\nAvailable path unit substates:");
6503 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6504 puts(path_state_to_string(i
));
6507 puts("\nAvailable scope unit substates:");
6508 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6509 puts(scope_state_to_string(i
));
6512 puts("\nAvailable service unit substates:");
6513 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6514 puts(service_state_to_string(i
));
6517 puts("\nAvailable slice unit substates:");
6518 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6519 puts(slice_state_to_string(i
));
6522 puts("\nAvailable snapshot unit substates:");
6523 for (i
= 0; i
< _SNAPSHOT_STATE_MAX
; i
++)
6524 puts(snapshot_state_to_string(i
));
6527 puts("\nAvailable socket unit substates:");
6528 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6529 puts(socket_state_to_string(i
));
6532 puts("\nAvailable swap unit substates:");
6533 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6534 puts(swap_state_to_string(i
));
6537 puts("\nAvailable target unit substates:");
6538 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6539 puts(target_state_to_string(i
));
6542 puts("\nAvailable timer unit substates:");
6543 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6544 puts(timer_state_to_string(i
));
6547 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6556 ARG_IGNORE_DEPENDENCIES
,
6568 ARG_NO_ASK_PASSWORD
,
6581 static const struct option options
[] = {
6582 { "help", no_argument
, NULL
, 'h' },
6583 { "version", no_argument
, NULL
, ARG_VERSION
},
6584 { "type", required_argument
, NULL
, 't' },
6585 { "property", required_argument
, NULL
, 'p' },
6586 { "all", no_argument
, NULL
, 'a' },
6587 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6588 { "after", no_argument
, NULL
, ARG_AFTER
},
6589 { "before", no_argument
, NULL
, ARG_BEFORE
},
6590 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6591 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6592 { "full", no_argument
, NULL
, 'l' },
6593 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6594 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6595 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6596 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6597 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6598 { "user", no_argument
, NULL
, ARG_USER
},
6599 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6600 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6601 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6602 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6603 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6604 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6605 { "quiet", no_argument
, NULL
, 'q' },
6606 { "root", required_argument
, NULL
, ARG_ROOT
},
6607 { "force", no_argument
, NULL
, ARG_FORCE
},
6608 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6609 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6610 { "signal", required_argument
, NULL
, 's' },
6611 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6612 { "host", required_argument
, NULL
, 'H' },
6613 { "machine", required_argument
, NULL
, 'M' },
6614 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6615 { "lines", required_argument
, NULL
, 'n' },
6616 { "output", required_argument
, NULL
, 'o' },
6617 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6618 { "state", required_argument
, NULL
, ARG_STATE
},
6619 { "recursive", no_argument
, NULL
, 'r' },
6620 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6621 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6622 { "now", no_argument
, NULL
, ARG_NOW
},
6623 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6632 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6633 arg_ask_password
= true;
6635 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6647 const char *word
, *state
;
6650 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6651 _cleanup_free_
char *type
;
6653 type
= strndup(word
, size
);
6657 if (streq(type
, "help")) {
6662 if (unit_type_from_string(type
) >= 0) {
6663 if (strv_push(&arg_types
, type
) < 0)
6669 /* It's much nicer to use --state= for
6670 * load states, but let's support this
6671 * in --types= too for compatibility
6672 * with old versions */
6673 if (unit_load_state_from_string(type
) >= 0) {
6674 if (strv_push(&arg_states
, type
) < 0)
6680 log_error("Unknown unit type or load state '%s'.", type
);
6681 log_info("Use -t help to see a list of allowed values.");
6689 /* Make sure that if the empty property list
6690 was specified, we won't show any properties. */
6691 if (isempty(optarg
) && !arg_properties
) {
6692 arg_properties
= new0(char*, 1);
6693 if (!arg_properties
)
6696 const char *word
, *state
;
6699 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6702 prop
= strndup(word
, size
);
6706 if (strv_consume(&arg_properties
, prop
) < 0)
6711 /* If the user asked for a particular
6712 * property, show it to him, even if it is
6724 arg_dependency
= DEPENDENCY_REVERSE
;
6728 arg_dependency
= DEPENDENCY_AFTER
;
6732 arg_dependency
= DEPENDENCY_BEFORE
;
6735 case ARG_SHOW_TYPES
:
6736 arg_show_types
= true;
6740 arg_job_mode
= optarg
;
6744 arg_job_mode
= "fail";
6747 case ARG_IRREVERSIBLE
:
6748 arg_job_mode
= "replace-irreversibly";
6751 case ARG_IGNORE_DEPENDENCIES
:
6752 arg_job_mode
= "ignore-dependencies";
6756 arg_scope
= UNIT_FILE_USER
;
6760 arg_scope
= UNIT_FILE_SYSTEM
;
6764 arg_scope
= UNIT_FILE_GLOBAL
;
6768 arg_no_block
= true;
6772 arg_no_legend
= true;
6776 arg_no_pager
= true;
6784 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6794 if (strv_extend(&arg_states
, "failed") < 0)
6812 arg_no_reload
= true;
6816 arg_kill_who
= optarg
;
6820 arg_signal
= signal_from_string_try_harder(optarg
);
6821 if (arg_signal
< 0) {
6822 log_error("Failed to parse signal string %s.", optarg
);
6827 case ARG_NO_ASK_PASSWORD
:
6828 arg_ask_password
= false;
6832 arg_transport
= BUS_TRANSPORT_REMOTE
;
6837 arg_transport
= BUS_TRANSPORT_MACHINE
;
6846 if (safe_atou(optarg
, &arg_lines
) < 0) {
6847 log_error("Failed to parse lines '%s'", optarg
);
6853 arg_output
= output_mode_from_string(optarg
);
6854 if (arg_output
< 0) {
6855 log_error("Unknown output '%s'.", optarg
);
6861 arg_ignore_inhibitors
= true;
6868 case ARG_FIRMWARE_SETUP
:
6869 arg_firmware_setup
= true;
6873 const char *word
, *state
;
6876 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6877 _cleanup_free_
char *s
= NULL
;
6879 s
= strndup(word
, size
);
6883 if (streq(s
, "help")) {
6888 if (strv_push(&arg_states
, s
) < 0)
6897 if (geteuid() != 0) {
6898 log_error("--recursive requires root privileges.");
6902 arg_recursive
= true;
6905 case ARG_PRESET_MODE
:
6907 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6908 if (arg_preset_mode
< 0) {
6909 log_error("Failed to parse preset mode: %s.", optarg
);
6920 if (strv_extend(&arg_wall
, optarg
) < 0)
6928 assert_not_reached("Unhandled option");
6931 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6932 log_error("Cannot access user instance remotely.");
6939 static int halt_parse_argv(int argc
, char *argv
[]) {
6948 static const struct option options
[] = {
6949 { "help", no_argument
, NULL
, ARG_HELP
},
6950 { "halt", no_argument
, NULL
, ARG_HALT
},
6951 { "poweroff", no_argument
, NULL
, 'p' },
6952 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6953 { "force", no_argument
, NULL
, 'f' },
6954 { "wtmp-only", no_argument
, NULL
, 'w' },
6955 { "no-wtmp", no_argument
, NULL
, 'd' },
6956 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6965 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6966 if (runlevel
== '0' || runlevel
== '6')
6969 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6977 arg_action
= ACTION_HALT
;
6981 if (arg_action
!= ACTION_REBOOT
)
6982 arg_action
= ACTION_POWEROFF
;
6986 arg_action
= ACTION_REBOOT
;
7008 /* Compatibility nops */
7015 assert_not_reached("Unhandled option");
7018 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7019 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7022 } else if (optind
< argc
) {
7023 log_error("Too many arguments.");
7030 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7034 if (streq(t
, "now"))
7036 else if (!strchr(t
, ':')) {
7039 if (safe_atou64(t
, &u
) < 0)
7042 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7051 hour
= strtol(t
, &e
, 10);
7052 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7055 minute
= strtol(e
+1, &e
, 10);
7056 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7059 n
= now(CLOCK_REALTIME
);
7060 s
= (time_t) (n
/ USEC_PER_SEC
);
7062 assert_se(localtime_r(&s
, &tm
));
7064 tm
.tm_hour
= (int) hour
;
7065 tm
.tm_min
= (int) minute
;
7068 assert_se(s
= mktime(&tm
));
7070 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7073 *_u
+= USEC_PER_DAY
;
7079 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7086 static const struct option options
[] = {
7087 { "help", no_argument
, NULL
, ARG_HELP
},
7088 { "halt", no_argument
, NULL
, 'H' },
7089 { "poweroff", no_argument
, NULL
, 'P' },
7090 { "reboot", no_argument
, NULL
, 'r' },
7091 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7092 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7102 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7110 arg_action
= ACTION_HALT
;
7114 arg_action
= ACTION_POWEROFF
;
7119 arg_action
= ACTION_KEXEC
;
7121 arg_action
= ACTION_REBOOT
;
7125 arg_action
= ACTION_KEXEC
;
7129 if (arg_action
!= ACTION_HALT
)
7130 arg_action
= ACTION_POWEROFF
;
7145 /* Compatibility nops */
7149 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7156 assert_not_reached("Unhandled option");
7159 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7160 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7162 log_error("Failed to parse time specification: %s", argv
[optind
]);
7166 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7168 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7169 /* No time argument for shutdown cancel */
7170 wall
= argv
+ optind
;
7171 else if (argc
> optind
+ 1)
7172 /* We skip the time argument */
7173 wall
= argv
+ optind
+ 1;
7176 arg_wall
= strv_copy(wall
);
7186 static int telinit_parse_argv(int argc
, char *argv
[]) {
7193 static const struct option options
[] = {
7194 { "help", no_argument
, NULL
, ARG_HELP
},
7195 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7199 static const struct {
7203 { '0', ACTION_POWEROFF
},
7204 { '6', ACTION_REBOOT
},
7205 { '1', ACTION_RESCUE
},
7206 { '2', ACTION_RUNLEVEL2
},
7207 { '3', ACTION_RUNLEVEL3
},
7208 { '4', ACTION_RUNLEVEL4
},
7209 { '5', ACTION_RUNLEVEL5
},
7210 { 's', ACTION_RESCUE
},
7211 { 'S', ACTION_RESCUE
},
7212 { 'q', ACTION_RELOAD
},
7213 { 'Q', ACTION_RELOAD
},
7214 { 'u', ACTION_REEXEC
},
7215 { 'U', ACTION_REEXEC
}
7224 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7239 assert_not_reached("Unhandled option");
7242 if (optind
>= argc
) {
7243 log_error("%s: required argument missing.", program_invocation_short_name
);
7247 if (optind
+ 1 < argc
) {
7248 log_error("Too many arguments.");
7252 if (strlen(argv
[optind
]) != 1) {
7253 log_error("Expected single character argument.");
7257 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7258 if (table
[i
].from
== argv
[optind
][0])
7261 if (i
>= ELEMENTSOF(table
)) {
7262 log_error("Unknown command '%s'.", argv
[optind
]);
7266 arg_action
= table
[i
].to
;
7273 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7279 static const struct option options
[] = {
7280 { "help", no_argument
, NULL
, ARG_HELP
},
7289 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7300 assert_not_reached("Unhandled option");
7303 if (optind
< argc
) {
7304 log_error("Too many arguments.");
7311 static int parse_argv(int argc
, char *argv
[]) {
7315 if (program_invocation_short_name
) {
7317 if (strstr(program_invocation_short_name
, "halt")) {
7318 arg_action
= ACTION_HALT
;
7319 return halt_parse_argv(argc
, argv
);
7320 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7321 arg_action
= ACTION_POWEROFF
;
7322 return halt_parse_argv(argc
, argv
);
7323 } else if (strstr(program_invocation_short_name
, "reboot")) {
7325 arg_action
= ACTION_KEXEC
;
7327 arg_action
= ACTION_REBOOT
;
7328 return halt_parse_argv(argc
, argv
);
7329 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7330 arg_action
= ACTION_POWEROFF
;
7331 return shutdown_parse_argv(argc
, argv
);
7332 } else if (strstr(program_invocation_short_name
, "init")) {
7334 if (sd_booted() > 0) {
7335 arg_action
= _ACTION_INVALID
;
7336 return telinit_parse_argv(argc
, argv
);
7338 /* Hmm, so some other init system is
7339 * running, we need to forward this
7340 * request to it. For now we simply
7341 * guess that it is Upstart. */
7343 execv(TELINIT
, argv
);
7345 log_error("Couldn't find an alternative telinit implementation to spawn.");
7349 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7350 arg_action
= ACTION_RUNLEVEL
;
7351 return runlevel_parse_argv(argc
, argv
);
7355 arg_action
= ACTION_SYSTEMCTL
;
7356 return systemctl_parse_argv(argc
, argv
);
7359 _pure_
static int action_to_runlevel(void) {
7361 static const char table
[_ACTION_MAX
] = {
7362 [ACTION_HALT
] = '0',
7363 [ACTION_POWEROFF
] = '0',
7364 [ACTION_REBOOT
] = '6',
7365 [ACTION_RUNLEVEL2
] = '2',
7366 [ACTION_RUNLEVEL3
] = '3',
7367 [ACTION_RUNLEVEL4
] = '4',
7368 [ACTION_RUNLEVEL5
] = '5',
7369 [ACTION_RESCUE
] = '1'
7372 assert(arg_action
< _ACTION_MAX
);
7374 return table
[arg_action
];
7377 static int talk_initctl(void) {
7378 #ifdef HAVE_SYSV_COMPAT
7379 struct init_request request
= {
7380 .magic
= INIT_MAGIC
,
7382 .cmd
= INIT_CMD_RUNLVL
7385 _cleanup_close_
int fd
= -1;
7389 rl
= action_to_runlevel();
7393 request
.runlevel
= rl
;
7395 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7397 if (errno
== ENOENT
)
7400 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7403 r
= loop_write(fd
, &request
, sizeof(request
), false);
7405 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7413 static int systemctl_main(int argc
, char *argv
[]) {
7415 static const Verb verbs
[] = {
7416 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
, list_units
},
7417 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7418 { "list-sockets", VERB_ANY
, VERB_ANY
, 0, list_sockets
},
7419 { "list-timers", VERB_ANY
, VERB_ANY
, 0, list_timers
},
7420 { "list-jobs", VERB_ANY
, VERB_ANY
, 0, list_jobs
},
7421 { "list-machines", VERB_ANY
, VERB_ANY
, 0, list_machines
},
7422 { "clear-jobs", VERB_ANY
, 1, 0, daemon_reload
},
7423 { "cancel", 2, VERB_ANY
, 0, cancel_job
},
7424 { "start", 2, VERB_ANY
, 0, start_unit
},
7425 { "stop", 2, VERB_ANY
, 0, start_unit
},
7426 { "condstop", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7427 { "reload", 2, VERB_ANY
, 0, start_unit
},
7428 { "restart", 2, VERB_ANY
, 0, start_unit
},
7429 { "try-restart", 2, VERB_ANY
, 0, start_unit
},
7430 { "reload-or-restart", 2, VERB_ANY
, 0, start_unit
},
7431 { "reload-or-try-restart", 2, VERB_ANY
, 0, start_unit
},
7432 { "force-reload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with SysV */
7433 { "condreload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7434 { "condrestart", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with RH */
7435 { "isolate", 2, 2, 0, start_unit
},
7436 { "kill", 2, VERB_ANY
, 0, kill_unit
},
7437 { "is-active", 2, VERB_ANY
, 0, check_unit_active
},
7438 { "check", 2, VERB_ANY
, 0, check_unit_active
},
7439 { "is-failed", 2, VERB_ANY
, 0, check_unit_failed
},
7440 { "show", VERB_ANY
, VERB_ANY
, 0, show
},
7441 { "cat", 2, VERB_ANY
, 0, cat
},
7442 { "status", VERB_ANY
, VERB_ANY
, 0, show
},
7443 { "help", VERB_ANY
, VERB_ANY
, 0, show
},
7444 { "snapshot", VERB_ANY
, 2, 0, snapshot
},
7445 { "delete", 2, VERB_ANY
, 0, delete_snapshot
},
7446 { "daemon-reload", VERB_ANY
, 1, 0, daemon_reload
},
7447 { "daemon-reexec", VERB_ANY
, 1, 0, daemon_reload
},
7448 { "show-environment", VERB_ANY
, 1, 0, show_environment
},
7449 { "set-environment", 2, VERB_ANY
, 0, set_environment
},
7450 { "unset-environment", 2, VERB_ANY
, 0, set_environment
},
7451 { "import-environment", VERB_ANY
, VERB_ANY
, 0, import_environment
},
7452 { "halt", VERB_ANY
, 1, 0, start_special
},
7453 { "poweroff", VERB_ANY
, 1, 0, start_special
},
7454 { "reboot", VERB_ANY
, 2, 0, start_special
},
7455 { "kexec", VERB_ANY
, 1, 0, start_special
},
7456 { "suspend", VERB_ANY
, 1, 0, start_special
},
7457 { "hibernate", VERB_ANY
, 1, 0, start_special
},
7458 { "hybrid-sleep", VERB_ANY
, 1, 0, start_special
},
7459 { "default", VERB_ANY
, 1, 0, start_special
},
7460 { "rescue", VERB_ANY
, 1, 0, start_special
},
7461 { "emergency", VERB_ANY
, 1, 0, start_special
},
7462 { "exit", VERB_ANY
, 2, 0, start_special
},
7463 { "reset-failed", VERB_ANY
, VERB_ANY
, 0, reset_failed
},
7464 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7465 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7466 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7467 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7468 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7469 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7470 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7471 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7472 { "link", 2, VERB_ANY
, 0, enable_unit
},
7473 { "switch-root", 2, VERB_ANY
, 0, switch_root
},
7474 { "list-dependencies", VERB_ANY
, 2, 0, list_dependencies
},
7475 { "set-default", 2, 2, 0, set_default
},
7476 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7477 { "set-property", 3, VERB_ANY
, 0, set_property
},
7478 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7479 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7480 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7481 { "edit", 2, VERB_ANY
, 0, edit
},
7485 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7488 static int reload_with_fallback(void) {
7490 /* First, try systemd via D-Bus. */
7491 if (daemon_reload(0, NULL
, NULL
) >= 0)
7494 /* Nothing else worked, so let's try signals */
7495 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7497 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7498 return log_error_errno(errno
, "kill() failed: %m");
7503 static int start_with_fallback(void) {
7505 /* First, try systemd via D-Bus. */
7506 if (start_unit(0, NULL
, NULL
) >= 0)
7509 /* Nothing else worked, so let's try
7511 if (talk_initctl() > 0)
7514 log_error("Failed to talk to init daemon.");
7518 static int halt_now(enum action a
) {
7520 /* The kernel will automaticall flush ATA disks and suchlike
7521 * on reboot(), but the file systems need to be synce'd
7522 * explicitly in advance. */
7525 /* Make sure C-A-D is handled by the kernel from this point
7527 (void) reboot(RB_ENABLE_CAD
);
7532 log_info("Halting.");
7533 (void) reboot(RB_HALT_SYSTEM
);
7536 case ACTION_POWEROFF
:
7537 log_info("Powering off.");
7538 (void) reboot(RB_POWER_OFF
);
7542 case ACTION_REBOOT
: {
7543 _cleanup_free_
char *param
= NULL
;
7545 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7546 log_info("Rebooting with argument '%s'.", param
);
7547 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7550 log_info("Rebooting.");
7551 (void) reboot(RB_AUTOBOOT
);
7556 assert_not_reached("Unknown action.");
7560 static int logind_schedule_shutdown(void) {
7563 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7564 char date
[FORMAT_TIMESTAMP_MAX
];
7569 (void) logind_set_wall_message();
7571 r
= acquire_bus(BUS_FULL
, &bus
);
7575 switch (arg_action
) {
7579 case ACTION_POWEROFF
:
7580 action
= "poweroff";
7595 action
= strjoina("dry-", action
);
7597 r
= sd_bus_call_method(
7599 "org.freedesktop.login1",
7600 "/org/freedesktop/login1",
7601 "org.freedesktop.login1.Manager",
7609 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7611 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7614 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7619 static int halt_main(void) {
7622 r
= logind_check_inhibitors(arg_action
);
7627 return logind_schedule_shutdown();
7629 if (geteuid() != 0) {
7630 if (arg_dry
|| arg_force
> 0) {
7631 log_error("Must be root.");
7635 /* Try logind if we are a normal user and no special
7636 * mode applies. Maybe PolicyKit allows us to shutdown
7638 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7639 r
= logind_reboot(arg_action
);
7642 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7643 /* requested operation is not
7644 * supported on the local system or
7645 * already in progress */
7647 /* on all other errors, try low-level operation */
7651 if (!arg_dry
&& !arg_force
)
7652 return start_with_fallback();
7654 assert(geteuid() == 0);
7657 if (sd_booted() > 0)
7658 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7660 r
= utmp_put_shutdown();
7662 log_warning_errno(r
, "Failed to write utmp record: %m");
7669 r
= halt_now(arg_action
);
7670 return log_error_errno(r
, "Failed to reboot: %m");
7673 static int runlevel_main(void) {
7674 int r
, runlevel
, previous
;
7676 r
= utmp_get_runlevel(&runlevel
, &previous
);
7683 previous
<= 0 ? 'N' : previous
,
7684 runlevel
<= 0 ? 'N' : runlevel
);
7689 static int logind_cancel_shutdown(void) {
7691 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7695 r
= acquire_bus(BUS_FULL
, &bus
);
7699 (void) logind_set_wall_message();
7701 r
= sd_bus_call_method(
7703 "org.freedesktop.login1",
7704 "/org/freedesktop/login1",
7705 "org.freedesktop.login1.Manager",
7706 "CancelScheduledShutdown",
7710 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7714 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7719 int main(int argc
, char*argv
[]) {
7722 setlocale(LC_ALL
, "");
7723 log_parse_environment();
7726 /* Explicitly not on_tty() to avoid setting cached value.
7727 * This becomes relevant for piping output which might be
7729 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7731 r
= parse_argv(argc
, argv
);
7735 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7736 log_info("Running in chroot, ignoring request.");
7741 /* systemctl_main() will print an error message for the bus
7742 * connection, but only if it needs to */
7744 switch (arg_action
) {
7746 case ACTION_SYSTEMCTL
:
7747 r
= systemctl_main(argc
, argv
);
7751 case ACTION_POWEROFF
:
7757 case ACTION_RUNLEVEL2
:
7758 case ACTION_RUNLEVEL3
:
7759 case ACTION_RUNLEVEL4
:
7760 case ACTION_RUNLEVEL5
:
7762 case ACTION_EMERGENCY
:
7763 case ACTION_DEFAULT
:
7764 r
= start_with_fallback();
7769 r
= reload_with_fallback();
7772 case ACTION_CANCEL_SHUTDOWN
:
7773 r
= logind_cancel_shutdown();
7776 case ACTION_RUNLEVEL
:
7777 r
= runlevel_main();
7780 case _ACTION_INVALID
:
7782 assert_not_reached("Unknown action");
7787 ask_password_agent_close();
7788 polkit_agent_close();
7790 strv_free(arg_types
);
7791 strv_free(arg_states
);
7792 strv_free(arg_properties
);
7794 strv_free(arg_wall
);
7799 return r
< 0 ? EXIT_FAILURE
: r
;