2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Marc-Antoine Perennou
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/reboot.h>
30 #include <sys/reboot.h>
31 #include <sys/socket.h>
35 #include "sd-daemon.h"
38 #include "alloc-util.h"
39 #include "bus-common-errors.h"
40 #include "bus-error.h"
41 #include "bus-message.h"
43 #include "cgroup-show.h"
44 #include "cgroup-util.h"
49 #include "exit-status.h"
52 #include "formats-util.h"
54 #include "glob-util.h"
55 #include "hostname-util.h"
60 #include "locale-util.h"
62 #include "logs-show.h"
66 #include "parse-util.h"
67 #include "path-lookup.h"
68 #include "path-util.h"
69 #include "process-util.h"
70 #include "rlimit-util.h"
72 #include "signal-util.h"
73 #include "socket-util.h"
74 #include "spawn-ask-password-agent.h"
75 #include "spawn-polkit-agent.h"
77 #include "stat-util.h"
79 #include "terminal-util.h"
80 #include "unit-name.h"
81 #include "user-util.h"
83 #include "utmp-wtmp.h"
87 static char **arg_types
= NULL
;
88 static char **arg_states
= NULL
;
89 static char **arg_properties
= NULL
;
90 static bool arg_all
= false;
91 static enum dependency
{
97 } arg_dependency
= DEPENDENCY_FORWARD
;
98 static const char *arg_job_mode
= "replace";
99 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
100 static bool arg_no_block
= false;
101 static bool arg_no_legend
= false;
102 static bool arg_no_pager
= false;
103 static bool arg_no_wtmp
= false;
104 static bool arg_no_wall
= false;
105 static bool arg_no_reload
= false;
106 static bool arg_value
= false;
107 static bool arg_show_types
= false;
108 static bool arg_ignore_inhibitors
= false;
109 static bool arg_dry
= false;
110 static bool arg_quiet
= false;
111 static bool arg_full
= false;
112 static bool arg_recursive
= false;
113 static int arg_force
= 0;
114 static bool arg_ask_password
= false;
115 static bool arg_runtime
= false;
116 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
117 static char **arg_wall
= NULL
;
118 static const char *arg_kill_who
= NULL
;
119 static int arg_signal
= SIGTERM
;
120 static char *arg_root
= NULL
;
121 static usec_t arg_when
= 0;
143 ACTION_CANCEL_SHUTDOWN
,
145 } arg_action
= ACTION_SYSTEMCTL
;
146 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
147 static const char *arg_host
= NULL
;
148 static unsigned arg_lines
= 10;
149 static OutputMode arg_output
= OUTPUT_SHORT
;
150 static bool arg_plain
= false;
151 static bool arg_firmware_setup
= false;
152 static bool arg_now
= false;
154 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
155 static int halt_now(enum action a
);
156 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
158 static bool original_stdout_is_tty
;
160 typedef enum BusFocus
{
161 BUS_FULL
, /* The full bus indicated via --system or --user */
162 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
166 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
168 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
171 assert(focus
< _BUS_FOCUS_MAX
);
174 /* We only go directly to the manager, if we are using a local transport */
175 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
178 if (!busses
[focus
]) {
181 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
183 if (focus
== BUS_MANAGER
)
184 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
186 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
188 return log_error_errno(r
, "Failed to connect to bus: %m");
190 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
193 *ret
= busses
[focus
];
197 static void release_busses(void) {
200 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
201 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
204 static void ask_password_agent_open_if_enabled(void) {
206 /* Open the password agent as a child process if necessary */
208 if (!arg_ask_password
)
211 if (arg_scope
!= UNIT_FILE_SYSTEM
)
214 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
217 ask_password_agent_open();
220 static void polkit_agent_open_if_enabled(void) {
222 /* Open the polkit agent as a child process if necessary */
224 if (!arg_ask_password
)
227 if (arg_scope
!= UNIT_FILE_SYSTEM
)
230 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
236 static OutputFlags
get_output_flags(void) {
238 arg_all
* OUTPUT_SHOW_ALL
|
239 arg_full
* OUTPUT_FULL_WIDTH
|
240 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
241 colors_enabled() * OUTPUT_COLOR
|
242 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
245 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
248 if (!sd_bus_error_is_set(error
))
251 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
252 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
253 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
254 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
255 return EXIT_NOPERMISSION
;
257 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
258 return EXIT_NOTINSTALLED
;
260 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
261 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
262 return EXIT_NOTIMPLEMENTED
;
264 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
265 return EXIT_NOTCONFIGURED
;
273 static bool install_client_side(void) {
275 /* Decides when to execute enable/disable/... operations
276 * client-side rather than server-side. */
278 if (running_in_chroot() > 0)
281 if (sd_booted() <= 0)
284 if (!isempty(arg_root
))
287 if (arg_scope
== UNIT_FILE_GLOBAL
)
290 /* Unsupported environment variable, mostly for debugging purposes */
291 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
297 static int compare_unit_info(const void *a
, const void *b
) {
298 const UnitInfo
*u
= a
, *v
= b
;
302 /* First, order by machine */
303 if (!u
->machine
&& v
->machine
)
305 if (u
->machine
&& !v
->machine
)
307 if (u
->machine
&& v
->machine
) {
308 r
= strcasecmp(u
->machine
, v
->machine
);
313 /* Second, order by unit type */
314 d1
= strrchr(u
->id
, '.');
315 d2
= strrchr(v
->id
, '.');
317 r
= strcasecmp(d1
, d2
);
322 /* Third, order by name */
323 return strcasecmp(u
->id
, v
->id
);
326 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
327 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
333 dot
= strrchr(u
->id
, '.');
337 if (!strv_find(arg_types
, dot
+1))
344 if (!strv_isempty(arg_states
))
347 /* By default show all units except the ones in inactive
348 * state and with no pending job */
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_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
530 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
531 _cleanup_(sd_bus_message_unrefp
) 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_(sd_bus_flush_close_unrefp
) 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(arg_no_pager
, false);
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_(sd_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_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
725 _cleanup_(sd_bus_message_unrefp
) 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(arg_no_pager
, false);
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_(sd_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_(sd_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(arg_no_pager
, false);
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
,
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_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1358 _cleanup_free_ UnitFileList
*units
= NULL
;
1366 pager_open(arg_no_pager
, false);
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_(sd_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"
1506 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1511 [DEPENDENCY_AFTER
] = "After\0",
1512 [DEPENDENCY_BEFORE
] = "Before\0",
1515 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1516 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1517 _cleanup_strv_free_
char **ret
= NULL
;
1518 _cleanup_free_
char *path
= NULL
;
1524 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1526 path
= unit_dbus_path_from_name(name
);
1530 r
= sd_bus_call_method(
1532 "org.freedesktop.systemd1",
1534 "org.freedesktop.DBus.Properties",
1538 "s", "org.freedesktop.systemd1.Unit");
1540 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1542 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1544 return bus_log_parse_error(r
);
1546 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1549 r
= sd_bus_message_read(reply
, "s", &prop
);
1551 return bus_log_parse_error(r
);
1553 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1554 r
= sd_bus_message_skip(reply
, "v");
1556 return bus_log_parse_error(r
);
1559 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1561 return bus_log_parse_error(r
);
1563 r
= bus_message_read_strv_extend(reply
, &ret
);
1565 return bus_log_parse_error(r
);
1567 r
= sd_bus_message_exit_container(reply
);
1569 return bus_log_parse_error(r
);
1572 r
= sd_bus_message_exit_container(reply
);
1574 return bus_log_parse_error(r
);
1578 return bus_log_parse_error(r
);
1580 r
= sd_bus_message_exit_container(reply
);
1582 return bus_log_parse_error(r
);
1590 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1591 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1593 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1595 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1598 return strcasecmp(*a
, *b
);
1601 static int list_dependencies_one(
1606 unsigned int branches
) {
1608 _cleanup_strv_free_
char **deps
= NULL
;
1616 r
= strv_extend(units
, name
);
1620 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1624 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1626 STRV_FOREACH(c
, deps
) {
1627 if (strv_contains(*units
, *c
)) {
1629 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1639 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1642 (void) get_state_one_unit(bus
, *c
, &active_state
);
1643 switch (active_state
) {
1645 case UNIT_RELOADING
:
1646 case UNIT_ACTIVATING
:
1647 on
= ansi_highlight_green();
1651 case UNIT_DEACTIVATING
:
1656 on
= ansi_highlight_red();
1660 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1663 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1667 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1668 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1675 strv_remove(*units
, name
);
1680 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1681 _cleanup_strv_free_
char **units
= NULL
;
1682 _cleanup_free_
char *unit
= NULL
;
1688 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1690 return log_error_errno(r
, "Failed to mangle unit name: %m");
1694 u
= SPECIAL_DEFAULT_TARGET
;
1696 pager_open(arg_no_pager
, false);
1698 r
= acquire_bus(BUS_MANAGER
, &bus
);
1704 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1707 struct machine_info
{
1711 char *control_group
;
1712 uint32_t n_failed_units
;
1717 static const struct bus_properties_map machine_info_property_map
[] = {
1718 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1719 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1720 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1721 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1722 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1726 static void machine_info_clear(struct machine_info
*info
) {
1730 free(info
->control_group
);
1735 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1741 for (i
= 0; i
< n
; i
++)
1742 machine_info_clear(&machine_infos
[i
]);
1744 free(machine_infos
);
1747 static int compare_machine_info(const void *a
, const void *b
) {
1748 const struct machine_info
*u
= a
, *v
= b
;
1750 if (u
->is_host
!= v
->is_host
)
1751 return u
->is_host
> v
->is_host
? -1 : 1;
1753 return strcasecmp(u
->name
, v
->name
);
1756 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1757 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1763 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1770 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1777 static bool output_show_machine(const char *name
, char **patterns
) {
1778 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1781 static int get_machine_list(
1783 struct machine_info
**_machine_infos
,
1786 struct machine_info
*machine_infos
= NULL
;
1787 _cleanup_strv_free_
char **m
= NULL
;
1788 _cleanup_free_
char *hn
= NULL
;
1793 hn
= gethostname_malloc();
1797 if (output_show_machine(hn
, patterns
)) {
1798 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1801 machine_infos
[c
].is_host
= true;
1802 machine_infos
[c
].name
= hn
;
1805 get_machine_properties(bus
, &machine_infos
[c
]);
1809 r
= sd_get_machine_names(&m
);
1811 return log_error_errno(r
, "Failed to get machine list: %m");
1813 STRV_FOREACH(i
, m
) {
1814 _cleanup_free_
char *class = NULL
;
1816 if (!output_show_machine(*i
, patterns
))
1819 sd_machine_get_class(*i
, &class);
1820 if (!streq_ptr(class, "container"))
1823 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1824 free_machines_list(machine_infos
, c
);
1828 machine_infos
[c
].is_host
= false;
1829 machine_infos
[c
].name
= strdup(*i
);
1830 if (!machine_infos
[c
].name
) {
1831 free_machines_list(machine_infos
, c
);
1835 get_machine_properties(NULL
, &machine_infos
[c
]);
1839 *_machine_infos
= machine_infos
;
1843 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1844 struct machine_info
*m
;
1847 namelen
= sizeof("NAME") - 1,
1848 statelen
= sizeof("STATE") - 1,
1849 failedlen
= sizeof("FAILED") - 1,
1850 jobslen
= sizeof("JOBS") - 1;
1852 assert(machine_infos
|| n
== 0);
1854 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1855 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1856 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1857 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1858 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1860 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1864 if (!arg_no_legend
) {
1868 printf("%-*s %-*s %-*s %-*s\n",
1871 failedlen
, "FAILED",
1875 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1876 const char *on_state
= "", *off_state
= "";
1877 const char *on_failed
= "", *off_failed
= "";
1878 bool circle
= false;
1880 if (streq_ptr(m
->state
, "degraded")) {
1881 on_state
= ansi_highlight_red();
1882 off_state
= ansi_normal();
1884 } else if (!streq_ptr(m
->state
, "running")) {
1885 on_state
= ansi_highlight_yellow();
1886 off_state
= ansi_normal();
1890 if (m
->n_failed_units
> 0) {
1891 on_failed
= ansi_highlight_red();
1892 off_failed
= ansi_normal();
1894 on_failed
= off_failed
= "";
1897 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1900 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1901 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1902 on_state
, statelen
, strna(m
->state
), off_state
,
1903 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1904 jobslen
, m
->n_jobs
);
1906 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1907 namelen
, strna(m
->name
),
1908 on_state
, statelen
, strna(m
->state
), off_state
,
1909 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1910 jobslen
, m
->n_jobs
);
1914 printf("\n%u machines listed.\n", n
);
1917 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1918 struct machine_info
*machine_infos
= NULL
;
1922 if (geteuid() != 0) {
1923 log_error("Must be root.");
1927 pager_open(arg_no_pager
, false);
1929 r
= acquire_bus(BUS_MANAGER
, &bus
);
1933 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1937 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1938 output_machines_list(machine_infos
, r
);
1939 free_machines_list(machine_infos
, r
);
1944 static int get_default(int argc
, char *argv
[], void *userdata
) {
1945 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1946 _cleanup_free_
char *_path
= NULL
;
1950 if (install_client_side()) {
1951 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1953 return log_error_errno(r
, "Failed to get default target: %m");
1957 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1960 r
= acquire_bus(BUS_MANAGER
, &bus
);
1964 r
= sd_bus_call_method(
1966 "org.freedesktop.systemd1",
1967 "/org/freedesktop/systemd1",
1968 "org.freedesktop.systemd1.Manager",
1974 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1976 r
= sd_bus_message_read(reply
, "s", &path
);
1978 return bus_log_parse_error(r
);
1982 printf("%s\n", path
);
1987 static int set_default(int argc
, char *argv
[], void *userdata
) {
1988 _cleanup_free_
char *unit
= NULL
;
1994 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1996 return log_error_errno(r
, "Failed to mangle unit name: %m");
1998 if (install_client_side()) {
1999 UnitFileChange
*changes
= NULL
;
2000 unsigned n_changes
= 0;
2002 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2003 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2004 unit_file_changes_free(changes
, n_changes
);
2007 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2008 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2011 polkit_agent_open_if_enabled();
2013 r
= acquire_bus(BUS_MANAGER
, &bus
);
2017 r
= sd_bus_call_method(
2019 "org.freedesktop.systemd1",
2020 "/org/freedesktop/systemd1",
2021 "org.freedesktop.systemd1.Manager",
2027 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2029 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2033 /* Try to reload if enabled */
2035 r
= daemon_reload(argc
, argv
, userdata
);
2045 const char *name
, *type
, *state
;
2048 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2049 unsigned id_len
, unit_len
, type_len
, state_len
;
2050 const struct job_info
*j
;
2051 const char *on
, *off
;
2052 bool shorten
= false;
2054 assert(n
== 0 || jobs
);
2057 if (!arg_no_legend
) {
2058 on
= ansi_highlight_green();
2059 off
= ansi_normal();
2061 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2066 pager_open(arg_no_pager
, false);
2068 id_len
= strlen("JOB");
2069 unit_len
= strlen("UNIT");
2070 type_len
= strlen("TYPE");
2071 state_len
= strlen("STATE");
2073 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2074 uint32_t id
= j
->id
;
2075 assert(j
->name
&& j
->type
&& j
->state
);
2077 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2078 unit_len
= MAX(unit_len
, strlen(j
->name
));
2079 type_len
= MAX(type_len
, strlen(j
->type
));
2080 state_len
= MAX(state_len
, strlen(j
->state
));
2083 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2084 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2089 printf("%*s %-*s %-*s %-*s\n",
2093 state_len
, "STATE");
2095 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2096 _cleanup_free_
char *e
= NULL
;
2098 if (streq(j
->state
, "running")) {
2099 on
= ansi_highlight();
2100 off
= ansi_normal();
2104 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2105 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2107 on
, unit_len
, e
? e
: j
->name
, off
,
2109 on
, state_len
, j
->state
, off
);
2112 if (!arg_no_legend
) {
2113 on
= ansi_highlight();
2114 off
= ansi_normal();
2116 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2120 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2121 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2124 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2125 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2126 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2127 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2128 _cleanup_free_
struct job_info
*jobs
= NULL
;
2134 bool skipped
= false;
2136 pager_open(arg_no_pager
, false);
2138 r
= acquire_bus(BUS_MANAGER
, &bus
);
2142 r
= sd_bus_call_method(
2144 "org.freedesktop.systemd1",
2145 "/org/freedesktop/systemd1",
2146 "org.freedesktop.systemd1.Manager",
2152 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2154 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2156 return bus_log_parse_error(r
);
2158 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2159 struct job_info job
= { id
, name
, type
, state
};
2161 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2166 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2172 return bus_log_parse_error(r
);
2174 r
= sd_bus_message_exit_container(reply
);
2176 return bus_log_parse_error(r
);
2178 output_jobs_list(jobs
, c
, skipped
);
2182 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2188 return daemon_reload(argc
, argv
, userdata
);
2190 polkit_agent_open_if_enabled();
2192 r
= acquire_bus(BUS_MANAGER
, &bus
);
2196 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2197 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2201 q
= safe_atou32(*name
, &id
);
2203 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2205 q
= sd_bus_call_method(
2207 "org.freedesktop.systemd1",
2208 "/org/freedesktop/systemd1",
2209 "org.freedesktop.systemd1.Manager",
2215 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2224 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2225 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2229 /* We ignore all errors here, since this is used to show a
2232 /* We don't use unit_dbus_path_from_name() directly since we
2233 * don't want to load the unit if it isn't loaded. */
2235 r
= sd_bus_call_method(
2237 "org.freedesktop.systemd1",
2238 "/org/freedesktop/systemd1",
2239 "org.freedesktop.systemd1.Manager",
2247 r
= sd_bus_message_read(reply
, "o", &path
);
2251 r
= sd_bus_get_property_trivial(
2253 "org.freedesktop.systemd1",
2255 "org.freedesktop.systemd1.Unit",
2265 static void warn_unit_file_changed(const char *name
) {
2266 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2267 ansi_highlight_red(),
2270 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2273 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2280 STRV_FOREACH(p
, lp
->search_path
) {
2281 _cleanup_free_
char *path
;
2283 path
= path_join(arg_root
, *p
, unit_name
);
2287 if (access(path
, F_OK
) == 0) {
2297 static int unit_find_paths(
2299 const char *unit_name
,
2301 char **fragment_path
,
2302 char ***dropin_paths
) {
2304 _cleanup_free_
char *path
= NULL
;
2305 _cleanup_strv_free_
char **dropins
= NULL
;
2309 * Finds where the unit is defined on disk. Returns 0 if the unit
2310 * is not found. Returns 1 if it is found, and sets
2311 * - the path to the unit in *path, if it exists on disk,
2312 * - and a strv of existing drop-ins in *dropins,
2313 * if the arg is not NULL and any dropins were found.
2317 assert(fragment_path
);
2320 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2321 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2322 _cleanup_free_
char *unit
= NULL
;
2324 unit
= unit_dbus_path_from_name(unit_name
);
2328 r
= sd_bus_get_property_string(
2330 "org.freedesktop.systemd1",
2332 "org.freedesktop.systemd1.Unit",
2337 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2340 r
= sd_bus_get_property_strv(
2342 "org.freedesktop.systemd1",
2344 "org.freedesktop.systemd1.Unit",
2349 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2352 _cleanup_set_free_ Set
*names
;
2354 names
= set_new(NULL
);
2358 r
= set_put(names
, unit_name
);
2360 return log_error_errno(r
, "Failed to add unit name: %m");
2362 r
= unit_file_find_path(lp
, unit_name
, &path
);
2367 _cleanup_free_
char *template = NULL
;
2369 r
= unit_name_template(unit_name
, &template);
2370 if (r
< 0 && r
!= -EINVAL
)
2371 return log_error_errno(r
, "Failed to determine template name: %m");
2373 r
= unit_file_find_path(lp
, template, &path
);
2380 r
= unit_file_find_dropin_paths(lp
->search_path
, NULL
, names
, &dropins
);
2388 if (!isempty(path
)) {
2389 *fragment_path
= path
;
2394 if (dropin_paths
&& !strv_isempty(dropins
)) {
2395 *dropin_paths
= dropins
;
2401 log_error("No files found for %s.", unit_name
);
2406 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2407 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2408 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2409 _cleanup_free_
char *buf
= NULL
;
2410 UnitActiveState state
;
2415 assert(active_state
);
2417 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2419 r
= sd_bus_call_method(
2421 "org.freedesktop.systemd1",
2422 "/org/freedesktop/systemd1",
2423 "org.freedesktop.systemd1.Manager",
2429 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2430 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2432 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2433 * considered inactive. */
2434 state
= UNIT_INACTIVE
;
2437 r
= sd_bus_message_read(reply
, "o", &path
);
2439 return bus_log_parse_error(r
);
2441 r
= sd_bus_get_property_string(
2443 "org.freedesktop.systemd1",
2445 "org.freedesktop.systemd1.Unit",
2450 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2452 state
= unit_active_state_from_string(buf
);
2453 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2454 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2459 *active_state
= state
;
2463 static int check_triggering_units(
2467 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2468 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2469 _cleanup_strv_free_
char **triggered_by
= NULL
;
2470 bool print_warning_label
= true;
2471 UnitActiveState active_state
;
2475 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2477 return log_error_errno(r
, "Failed to mangle unit name: %m");
2479 path
= unit_dbus_path_from_name(n
);
2483 r
= sd_bus_get_property_string(
2485 "org.freedesktop.systemd1",
2487 "org.freedesktop.systemd1.Unit",
2492 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2494 if (streq(load_state
, "masked"))
2497 r
= sd_bus_get_property_strv(
2499 "org.freedesktop.systemd1",
2501 "org.freedesktop.systemd1.Unit",
2506 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2508 STRV_FOREACH(i
, triggered_by
) {
2509 r
= get_state_one_unit(bus
, *i
, &active_state
);
2513 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2516 if (print_warning_label
) {
2517 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2518 print_warning_label
= false;
2521 log_warning(" %s", *i
);
2527 static const struct {
2530 } unit_actions
[] = {
2531 { "start", "StartUnit" },
2532 { "stop", "StopUnit" },
2533 { "condstop", "StopUnit" },
2534 { "reload", "ReloadUnit" },
2535 { "restart", "RestartUnit" },
2536 { "try-restart", "TryRestartUnit" },
2537 { "condrestart", "TryRestartUnit" },
2538 { "reload-or-restart", "ReloadOrRestartUnit" },
2539 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2540 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2541 { "condreload", "ReloadOrTryRestartUnit" },
2542 { "force-reload", "ReloadOrTryRestartUnit" }
2545 static const char *verb_to_method(const char *verb
) {
2548 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2549 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2550 return unit_actions
[i
].method
;
2555 static const char *method_to_verb(const char *method
) {
2558 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2559 if (streq_ptr(unit_actions
[i
].method
, method
))
2560 return unit_actions
[i
].verb
;
2565 static int start_unit_one(
2570 sd_bus_error
*error
,
2571 BusWaitForJobs
*w
) {
2573 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2582 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2584 r
= sd_bus_call_method(
2586 "org.freedesktop.systemd1",
2587 "/org/freedesktop/systemd1",
2588 "org.freedesktop.systemd1.Manager",
2596 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2597 /* There's always a fallback possible for
2598 * legacy actions. */
2599 return -EADDRNOTAVAIL
;
2601 verb
= method_to_verb(method
);
2603 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2605 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2606 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2607 log_error("See %s logs and 'systemctl%s status %s' for details.",
2608 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2609 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2615 r
= sd_bus_message_read(reply
, "o", &path
);
2617 return bus_log_parse_error(r
);
2619 if (need_daemon_reload(bus
, name
) > 0)
2620 warn_unit_file_changed(name
);
2623 log_debug("Adding %s to the set", path
);
2624 r
= bus_wait_for_jobs_add(w
, path
);
2632 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2633 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2640 STRV_FOREACH(name
, names
) {
2644 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2646 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2648 return log_error_errno(r
, "Failed to mangle name: %m");
2650 if (string_is_glob(t
))
2651 r
= strv_consume(&globs
, t
);
2653 r
= strv_consume(&mangled
, t
);
2658 /* Query the manager only if any of the names are a glob, since
2659 * this is fairly expensive */
2660 if (!strv_isempty(globs
)) {
2661 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2662 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2663 size_t allocated
, n
;
2665 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2669 n
= strv_length(mangled
);
2672 for (i
= 0; i
< r
; i
++) {
2673 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2676 mangled
[n
] = strdup(unit_infos
[i
].id
);
2680 mangled
[++n
] = NULL
;
2685 mangled
= NULL
; /* do not free */
2690 static const struct {
2694 } action_table
[_ACTION_MAX
] = {
2695 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2696 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2697 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2698 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2699 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2700 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2701 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2702 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2703 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2704 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2705 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2706 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2707 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2708 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2709 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2712 static enum action
verb_to_action(const char *verb
) {
2715 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2716 if (streq_ptr(action_table
[i
].verb
, verb
))
2719 return _ACTION_INVALID
;
2722 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2723 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2724 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2725 _cleanup_strv_free_
char **names
= NULL
;
2730 ask_password_agent_open_if_enabled();
2731 polkit_agent_open_if_enabled();
2733 r
= acquire_bus(BUS_MANAGER
, &bus
);
2737 if (arg_action
== ACTION_SYSTEMCTL
) {
2740 method
= verb_to_method(argv
[0]);
2741 action
= verb_to_action(argv
[0]);
2743 if (streq(argv
[0], "isolate")) {
2747 mode
= action_table
[action
].mode
?: arg_job_mode
;
2749 one_name
= action_table
[action
].target
;
2751 assert(arg_action
< ELEMENTSOF(action_table
));
2752 assert(action_table
[arg_action
].target
);
2754 method
= "StartUnit";
2756 mode
= action_table
[arg_action
].mode
;
2757 one_name
= action_table
[arg_action
].target
;
2761 names
= strv_new(one_name
, NULL
);
2763 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2765 return log_error_errno(r
, "Failed to expand names: %m");
2768 if (!arg_no_block
) {
2769 r
= bus_wait_for_jobs_new(bus
, &w
);
2771 return log_error_errno(r
, "Could not watch jobs: %m");
2774 STRV_FOREACH(name
, names
) {
2775 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2778 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2779 if (r
>= 0 && q
< 0)
2780 r
= translate_bus_error_to_exit_status(q
, &error
);
2783 if (!arg_no_block
) {
2784 int q
, arg_count
= 0;
2785 const char* extra_args
[4] = {};
2787 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2788 extra_args
[arg_count
++] = "--user";
2790 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2791 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2792 extra_args
[arg_count
++] = "-H";
2793 extra_args
[arg_count
++] = arg_host
;
2794 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2795 extra_args
[arg_count
++] = "-M";
2796 extra_args
[arg_count
++] = arg_host
;
2799 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2803 /* When stopping units, warn if they can still be triggered by
2804 * another active unit (socket, path, timer) */
2805 if (!arg_quiet
&& streq(method
, "StopUnit"))
2806 STRV_FOREACH(name
, names
)
2807 check_triggering_units(bus
, *name
);
2813 static int logind_set_wall_message(void) {
2815 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2817 _cleanup_free_
char *m
= NULL
;
2820 r
= acquire_bus(BUS_FULL
, &bus
);
2824 m
= strv_join(arg_wall
, " ");
2828 r
= sd_bus_call_method(
2830 "org.freedesktop.login1",
2831 "/org/freedesktop/login1",
2832 "org.freedesktop.login1.Manager",
2841 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2847 /* Ask systemd-logind, which might grant access to unprivileged users
2848 * through PolicyKit */
2849 static int logind_reboot(enum action a
) {
2851 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2852 const char *method
, *description
;
2856 polkit_agent_open_if_enabled();
2857 (void) logind_set_wall_message();
2859 r
= acquire_bus(BUS_FULL
, &bus
);
2867 description
= "reboot system";
2870 case ACTION_POWEROFF
:
2871 method
= "PowerOff";
2872 description
= "power off system";
2875 case ACTION_SUSPEND
:
2877 description
= "suspend system";
2880 case ACTION_HIBERNATE
:
2881 method
= "Hibernate";
2882 description
= "hibernate system";
2885 case ACTION_HYBRID_SLEEP
:
2886 method
= "HybridSleep";
2887 description
= "put system into hybrid sleep";
2894 r
= sd_bus_call_method(
2896 "org.freedesktop.login1",
2897 "/org/freedesktop/login1",
2898 "org.freedesktop.login1.Manager",
2902 "b", arg_ask_password
);
2904 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2912 static int logind_check_inhibitors(enum action a
) {
2914 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2915 _cleanup_strv_free_
char **sessions
= NULL
;
2916 const char *what
, *who
, *why
, *mode
;
2923 if (arg_ignore_inhibitors
|| arg_force
> 0)
2935 r
= acquire_bus(BUS_FULL
, &bus
);
2939 r
= sd_bus_call_method(
2941 "org.freedesktop.login1",
2942 "/org/freedesktop/login1",
2943 "org.freedesktop.login1.Manager",
2949 /* If logind is not around, then there are no inhibitors... */
2952 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2954 return bus_log_parse_error(r
);
2956 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2957 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2958 _cleanup_strv_free_
char **sv
= NULL
;
2960 if (!streq(mode
, "block"))
2963 sv
= strv_split(what
, ":");
2967 if ((pid_t
) pid
< 0)
2968 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2970 if (!strv_contains(sv
,
2975 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2978 get_process_comm(pid
, &comm
);
2979 user
= uid_to_name(uid
);
2981 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2982 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2987 return bus_log_parse_error(r
);
2989 r
= sd_bus_message_exit_container(reply
);
2991 return bus_log_parse_error(r
);
2993 /* Check for current sessions */
2994 sd_get_sessions(&sessions
);
2995 STRV_FOREACH(s
, sessions
) {
2996 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2998 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3001 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3004 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3007 sd_session_get_tty(*s
, &tty
);
3008 sd_session_get_seat(*s
, &seat
);
3009 sd_session_get_service(*s
, &service
);
3010 user
= uid_to_name(uid
);
3012 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3019 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3020 action_table
[a
].verb
);
3028 static int logind_prepare_firmware_setup(void) {
3030 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3034 r
= acquire_bus(BUS_FULL
, &bus
);
3038 r
= sd_bus_call_method(
3040 "org.freedesktop.login1",
3041 "/org/freedesktop/login1",
3042 "org.freedesktop.login1.Manager",
3043 "SetRebootToFirmwareSetup",
3048 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3052 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3057 static int prepare_firmware_setup(void) {
3060 if (!arg_firmware_setup
)
3063 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3065 r
= efi_set_reboot_to_firmware(true);
3067 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3072 return logind_prepare_firmware_setup();
3075 static int set_exit_code(uint8_t code
) {
3076 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3080 r
= acquire_bus(BUS_MANAGER
, &bus
);
3084 r
= sd_bus_call_method(
3086 "org.freedesktop.systemd1",
3087 "/org/freedesktop/systemd1",
3088 "org.freedesktop.systemd1.Manager",
3094 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3099 static int start_special(int argc
, char *argv
[], void *userdata
) {
3105 a
= verb_to_action(argv
[0]);
3107 r
= logind_check_inhibitors(a
);
3111 if (arg_force
>= 2 && geteuid() != 0) {
3112 log_error("Must be root.");
3116 r
= prepare_firmware_setup();
3120 if (a
== ACTION_REBOOT
&& argc
> 1) {
3121 r
= update_reboot_parameter_and_warn(argv
[1]);
3125 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3128 /* If the exit code is not given on the command line,
3129 * don't reset it to zero: just keep it as it might
3130 * have been set previously. */
3132 r
= safe_atou8(argv
[1], &code
);
3134 return log_error_errno(r
, "Invalid exit code.");
3136 r
= set_exit_code(code
);
3141 if (arg_force
>= 2 &&
3148 if (arg_force
>= 1 &&
3155 return daemon_reload(argc
, argv
, userdata
);
3157 /* First try logind, to allow authentication with polkit */
3163 ACTION_HYBRID_SLEEP
)) {
3164 r
= logind_reboot(a
);
3167 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3168 /* requested operation is not supported or already in progress */
3171 /* On all other errors, try low-level operation */
3174 return start_unit(argc
, argv
, userdata
);
3177 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3178 _cleanup_strv_free_
char **names
= NULL
;
3179 UnitActiveState active_state
;
3185 r
= acquire_bus(BUS_MANAGER
, &bus
);
3189 r
= expand_names(bus
, args
, NULL
, &names
);
3191 return log_error_errno(r
, "Failed to expand names: %m");
3193 STRV_FOREACH(name
, names
) {
3194 r
= get_state_one_unit(bus
, *name
, &active_state
);
3199 puts(unit_active_state_to_string(active_state
));
3201 for (i
= 0; i
< nb_states
; ++i
)
3202 if (good_states
[i
] == active_state
)
3206 /* use the given return code for the case that we won't find
3207 * any unit which matches the list */
3208 return found
? 0 : code
;
3211 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3212 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3213 /* According to LSB: 3, "program is not running" */
3214 return check_unit_generic(3, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3217 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3218 const UnitActiveState states
[] = { UNIT_FAILED
};
3219 return check_unit_generic(1, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3222 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3223 _cleanup_strv_free_
char **names
= NULL
;
3224 char *kill_who
= NULL
, **name
;
3228 polkit_agent_open_if_enabled();
3230 r
= acquire_bus(BUS_MANAGER
, &bus
);
3235 arg_kill_who
= "all";
3237 /* --fail was specified */
3238 if (streq(arg_job_mode
, "fail"))
3239 kill_who
= strjoina(arg_kill_who
, "-fail");
3241 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3243 return log_error_errno(r
, "Failed to expand names: %m");
3245 STRV_FOREACH(name
, names
) {
3246 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3248 q
= sd_bus_call_method(
3250 "org.freedesktop.systemd1",
3251 "/org/freedesktop/systemd1",
3252 "org.freedesktop.systemd1.Manager",
3256 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3258 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3267 typedef struct ExecStatusInfo
{
3275 usec_t start_timestamp
;
3276 usec_t exit_timestamp
;
3281 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3284 static void exec_status_info_free(ExecStatusInfo
*i
) {
3293 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3294 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3297 int32_t code
, status
;
3303 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3305 return bus_log_parse_error(r
);
3309 r
= sd_bus_message_read(m
, "s", &path
);
3311 return bus_log_parse_error(r
);
3313 i
->path
= strdup(path
);
3317 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3319 return bus_log_parse_error(r
);
3321 r
= sd_bus_message_read(m
,
3324 &start_timestamp
, &start_timestamp_monotonic
,
3325 &exit_timestamp
, &exit_timestamp_monotonic
,
3329 return bus_log_parse_error(r
);
3332 i
->start_timestamp
= (usec_t
) start_timestamp
;
3333 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3334 i
->pid
= (pid_t
) pid
;
3338 r
= sd_bus_message_exit_container(m
);
3340 return bus_log_parse_error(r
);
3345 typedef struct UnitStatusInfo
{
3347 const char *load_state
;
3348 const char *active_state
;
3349 const char *sub_state
;
3350 const char *unit_file_state
;
3351 const char *unit_file_preset
;
3353 const char *description
;
3354 const char *following
;
3356 char **documentation
;
3358 const char *fragment_path
;
3359 const char *source_path
;
3360 const char *control_group
;
3362 char **dropin_paths
;
3364 const char *load_error
;
3367 usec_t inactive_exit_timestamp
;
3368 usec_t inactive_exit_timestamp_monotonic
;
3369 usec_t active_enter_timestamp
;
3370 usec_t active_exit_timestamp
;
3371 usec_t inactive_enter_timestamp
;
3373 bool need_daemon_reload
;
3379 const char *status_text
;
3380 const char *pid_file
;
3384 usec_t start_timestamp
;
3385 usec_t exit_timestamp
;
3387 int exit_code
, exit_status
;
3389 usec_t condition_timestamp
;
3390 bool condition_result
;
3391 bool failed_condition_trigger
;
3392 bool failed_condition_negate
;
3393 const char *failed_condition
;
3394 const char *failed_condition_parameter
;
3396 usec_t assert_timestamp
;
3398 bool failed_assert_trigger
;
3399 bool failed_assert_negate
;
3400 const char *failed_assert
;
3401 const char *failed_assert_parameter
;
3404 unsigned n_accepted
;
3405 unsigned n_connections
;
3408 /* Pairs of type, path */
3412 const char *sysfs_path
;
3414 /* Mount, Automount */
3421 uint64_t memory_current
;
3422 uint64_t memory_limit
;
3423 uint64_t cpu_usage_nsec
;
3424 uint64_t tasks_current
;
3427 LIST_HEAD(ExecStatusInfo
, exec
);
3430 static void print_status_info(
3435 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3437 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3438 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3444 /* This shows pretty information about a unit. See
3445 * print_property() for a low-level property printer */
3447 if (streq_ptr(i
->active_state
, "failed")) {
3448 active_on
= ansi_highlight_red();
3449 active_off
= ansi_normal();
3450 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3451 active_on
= ansi_highlight_green();
3452 active_off
= ansi_normal();
3454 active_on
= active_off
= "";
3456 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3458 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3459 printf(" - %s", i
->description
);
3464 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3466 if (streq_ptr(i
->load_state
, "error")) {
3467 on
= ansi_highlight_red();
3468 off
= ansi_normal();
3472 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3474 if (i
->load_error
!= 0)
3475 printf(" Loaded: %s%s%s (Reason: %s)\n",
3476 on
, strna(i
->load_state
), off
, i
->load_error
);
3477 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3478 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3479 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3480 else if (path
&& !isempty(i
->unit_file_state
))
3481 printf(" Loaded: %s%s%s (%s; %s)\n",
3482 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3484 printf(" Loaded: %s%s%s (%s)\n",
3485 on
, strna(i
->load_state
), off
, path
);
3487 printf(" Loaded: %s%s%s\n",
3488 on
, strna(i
->load_state
), off
);
3491 printf("Transient: yes\n");
3493 if (!strv_isempty(i
->dropin_paths
)) {
3494 _cleanup_free_
char *dir
= NULL
;
3498 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3499 if (! dir
|| last
) {
3500 printf(dir
? " " : " Drop-In: ");
3504 dir
= dirname_malloc(*dropin
);
3510 printf("%s\n %s", dir
,
3511 draw_special_char(DRAW_TREE_RIGHT
));
3514 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3516 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3520 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3522 printf(" Active: %s%s (%s)%s",
3523 active_on
, strna(i
->active_state
), ss
, active_off
);
3525 printf(" Active: %s%s%s",
3526 active_on
, strna(i
->active_state
), active_off
);
3528 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3529 printf(" (Result: %s)", i
->result
);
3531 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3532 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3533 (streq_ptr(i
->active_state
, "inactive") ||
3534 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3535 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3536 i
->active_exit_timestamp
;
3538 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3539 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3542 printf(" since %s; %s\n", s2
, s1
);
3544 printf(" since %s\n", s2
);
3548 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3549 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3550 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3552 printf("Condition: start %scondition failed%s at %s%s%s\n",
3553 ansi_highlight_yellow(), ansi_normal(),
3554 s2
, s1
? "; " : "", strempty(s1
));
3555 if (i
->failed_condition_trigger
)
3556 printf(" none of the trigger conditions were met\n");
3557 else if (i
->failed_condition
)
3558 printf(" %s=%s%s was not met\n",
3559 i
->failed_condition
,
3560 i
->failed_condition_negate
? "!" : "",
3561 i
->failed_condition_parameter
);
3564 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3565 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3566 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3568 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3569 ansi_highlight_red(), ansi_normal(),
3570 s2
, s1
? "; " : "", strempty(s1
));
3571 if (i
->failed_assert_trigger
)
3572 printf(" none of the trigger assertions were met\n");
3573 else if (i
->failed_assert
)
3574 printf(" %s=%s%s was not met\n",
3576 i
->failed_assert_negate
? "!" : "",
3577 i
->failed_assert_parameter
);
3581 printf(" Device: %s\n", i
->sysfs_path
);
3583 printf(" Where: %s\n", i
->where
);
3585 printf(" What: %s\n", i
->what
);
3587 STRV_FOREACH(t
, i
->documentation
)
3588 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3590 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3591 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3594 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3596 LIST_FOREACH(exec
, p
, i
->exec
) {
3597 _cleanup_free_
char *argv
= NULL
;
3600 /* Only show exited processes here */
3604 argv
= strv_join(p
->argv
, " ");
3605 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3607 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3609 on
= ansi_highlight_red();
3610 off
= ansi_normal();
3614 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3616 if (p
->code
== CLD_EXITED
) {
3619 printf("status=%i", p
->status
);
3621 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3626 printf("signal=%s", signal_to_string(p
->status
));
3628 printf(")%s\n", off
);
3630 if (i
->main_pid
== p
->pid
&&
3631 i
->start_timestamp
== p
->start_timestamp
&&
3632 i
->exit_timestamp
== p
->start_timestamp
)
3633 /* Let's not show this twice */
3636 if (p
->pid
== i
->control_pid
)
3640 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3641 if (i
->main_pid
> 0) {
3642 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3645 _cleanup_free_
char *comm
= NULL
;
3646 get_process_comm(i
->main_pid
, &comm
);
3648 printf(" (%s)", comm
);
3649 } else if (i
->exit_code
> 0) {
3650 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3652 if (i
->exit_code
== CLD_EXITED
) {
3655 printf("status=%i", i
->exit_status
);
3657 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3662 printf("signal=%s", signal_to_string(i
->exit_status
));
3666 if (i
->control_pid
> 0)
3670 if (i
->control_pid
> 0) {
3671 _cleanup_free_
char *c
= NULL
;
3673 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3675 get_process_comm(i
->control_pid
, &c
);
3684 printf(" Status: \"%s\"\n", i
->status_text
);
3685 if (i
->status_errno
> 0)
3686 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3688 if (i
->tasks_current
!= (uint64_t) -1) {
3689 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3691 if (i
->tasks_max
!= (uint64_t) -1)
3692 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3697 if (i
->memory_current
!= (uint64_t) -1) {
3698 char buf
[FORMAT_BYTES_MAX
];
3700 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3702 if (i
->memory_limit
!= (uint64_t) -1)
3703 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3708 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3709 char buf
[FORMAT_TIMESPAN_MAX
];
3710 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3713 if (i
->control_group
&&
3714 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3715 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3718 printf(" CGroup: %s\n", i
->control_group
);
3720 if (IN_SET(arg_transport
,
3721 BUS_TRANSPORT_LOCAL
,
3722 BUS_TRANSPORT_MACHINE
)) {
3725 static const char prefix
[] = " ";
3728 if (c
> sizeof(prefix
) - 1)
3729 c
-= sizeof(prefix
) - 1;
3733 if (i
->main_pid
> 0)
3734 extra
[k
++] = i
->main_pid
;
3736 if (i
->control_pid
> 0)
3737 extra
[k
++] = i
->control_pid
;
3739 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3743 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3744 show_journal_by_unit(
3749 i
->inactive_exit_timestamp_monotonic
,
3752 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3753 SD_JOURNAL_LOCAL_ONLY
,
3754 arg_scope
== UNIT_FILE_SYSTEM
,
3757 if (i
->need_daemon_reload
)
3758 warn_unit_file_changed(i
->id
);
3761 static void show_unit_help(UnitStatusInfo
*i
) {
3766 if (!i
->documentation
) {
3767 log_info("Documentation for %s not known.", i
->id
);
3771 STRV_FOREACH(p
, i
->documentation
)
3772 if (startswith(*p
, "man:"))
3773 show_man_page(*p
+ 4, false);
3775 log_info("Can't show: %s", *p
);
3778 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3785 switch (contents
[0]) {
3787 case SD_BUS_TYPE_STRING
: {
3790 r
= sd_bus_message_read(m
, "s", &s
);
3792 return bus_log_parse_error(r
);
3795 if (streq(name
, "Id"))
3797 else if (streq(name
, "LoadState"))
3799 else if (streq(name
, "ActiveState"))
3800 i
->active_state
= s
;
3801 else if (streq(name
, "SubState"))
3803 else if (streq(name
, "Description"))
3805 else if (streq(name
, "FragmentPath"))
3806 i
->fragment_path
= s
;
3807 else if (streq(name
, "SourcePath"))
3810 else if (streq(name
, "DefaultControlGroup")) {
3812 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3814 i
->control_group
= e
;
3817 else if (streq(name
, "ControlGroup"))
3818 i
->control_group
= s
;
3819 else if (streq(name
, "StatusText"))
3821 else if (streq(name
, "PIDFile"))
3823 else if (streq(name
, "SysFSPath"))
3825 else if (streq(name
, "Where"))
3827 else if (streq(name
, "What"))
3829 else if (streq(name
, "Following"))
3831 else if (streq(name
, "UnitFileState"))
3832 i
->unit_file_state
= s
;
3833 else if (streq(name
, "UnitFilePreset"))
3834 i
->unit_file_preset
= s
;
3835 else if (streq(name
, "Result"))
3842 case SD_BUS_TYPE_BOOLEAN
: {
3845 r
= sd_bus_message_read(m
, "b", &b
);
3847 return bus_log_parse_error(r
);
3849 if (streq(name
, "Accept"))
3851 else if (streq(name
, "NeedDaemonReload"))
3852 i
->need_daemon_reload
= b
;
3853 else if (streq(name
, "ConditionResult"))
3854 i
->condition_result
= b
;
3855 else if (streq(name
, "AssertResult"))
3856 i
->assert_result
= b
;
3857 else if (streq(name
, "Transient"))
3863 case SD_BUS_TYPE_UINT32
: {
3866 r
= sd_bus_message_read(m
, "u", &u
);
3868 return bus_log_parse_error(r
);
3870 if (streq(name
, "MainPID")) {
3872 i
->main_pid
= (pid_t
) u
;
3875 } else if (streq(name
, "ControlPID"))
3876 i
->control_pid
= (pid_t
) u
;
3877 else if (streq(name
, "ExecMainPID")) {
3879 i
->main_pid
= (pid_t
) u
;
3880 } else if (streq(name
, "NAccepted"))
3882 else if (streq(name
, "NConnections"))
3883 i
->n_connections
= u
;
3888 case SD_BUS_TYPE_INT32
: {
3891 r
= sd_bus_message_read(m
, "i", &j
);
3893 return bus_log_parse_error(r
);
3895 if (streq(name
, "ExecMainCode"))
3896 i
->exit_code
= (int) j
;
3897 else if (streq(name
, "ExecMainStatus"))
3898 i
->exit_status
= (int) j
;
3899 else if (streq(name
, "StatusErrno"))
3900 i
->status_errno
= (int) j
;
3905 case SD_BUS_TYPE_UINT64
: {
3908 r
= sd_bus_message_read(m
, "t", &u
);
3910 return bus_log_parse_error(r
);
3912 if (streq(name
, "ExecMainStartTimestamp"))
3913 i
->start_timestamp
= (usec_t
) u
;
3914 else if (streq(name
, "ExecMainExitTimestamp"))
3915 i
->exit_timestamp
= (usec_t
) u
;
3916 else if (streq(name
, "ActiveEnterTimestamp"))
3917 i
->active_enter_timestamp
= (usec_t
) u
;
3918 else if (streq(name
, "InactiveEnterTimestamp"))
3919 i
->inactive_enter_timestamp
= (usec_t
) u
;
3920 else if (streq(name
, "InactiveExitTimestamp"))
3921 i
->inactive_exit_timestamp
= (usec_t
) u
;
3922 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3923 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3924 else if (streq(name
, "ActiveExitTimestamp"))
3925 i
->active_exit_timestamp
= (usec_t
) u
;
3926 else if (streq(name
, "ConditionTimestamp"))
3927 i
->condition_timestamp
= (usec_t
) u
;
3928 else if (streq(name
, "AssertTimestamp"))
3929 i
->assert_timestamp
= (usec_t
) u
;
3930 else if (streq(name
, "MemoryCurrent"))
3931 i
->memory_current
= u
;
3932 else if (streq(name
, "MemoryLimit"))
3933 i
->memory_limit
= u
;
3934 else if (streq(name
, "TasksCurrent"))
3935 i
->tasks_current
= u
;
3936 else if (streq(name
, "TasksMax"))
3938 else if (streq(name
, "CPUUsageNSec"))
3939 i
->cpu_usage_nsec
= u
;
3944 case SD_BUS_TYPE_ARRAY
:
3946 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3947 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3949 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3951 return bus_log_parse_error(r
);
3953 info
= new0(ExecStatusInfo
, 1);
3957 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3959 info
->name
= strdup(name
);
3963 LIST_PREPEND(exec
, i
->exec
, info
);
3965 info
= new0(ExecStatusInfo
, 1);
3971 return bus_log_parse_error(r
);
3973 r
= sd_bus_message_exit_container(m
);
3975 return bus_log_parse_error(r
);
3979 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3980 const char *type
, *path
;
3982 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3984 return bus_log_parse_error(r
);
3986 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3988 r
= strv_extend(&i
->listen
, type
);
3992 r
= strv_extend(&i
->listen
, path
);
3997 return bus_log_parse_error(r
);
3999 r
= sd_bus_message_exit_container(m
);
4001 return bus_log_parse_error(r
);
4005 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4007 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4009 return bus_log_parse_error(r
);
4011 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4013 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4015 return bus_log_parse_error(r
);
4017 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4018 const char *cond
, *param
;
4019 int trigger
, negate
;
4022 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4024 return bus_log_parse_error(r
);
4026 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4027 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4028 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4029 i
->failed_condition
= cond
;
4030 i
->failed_condition_trigger
= trigger
;
4031 i
->failed_condition_negate
= negate
;
4032 i
->failed_condition_parameter
= param
;
4036 return bus_log_parse_error(r
);
4038 r
= sd_bus_message_exit_container(m
);
4040 return bus_log_parse_error(r
);
4042 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4043 const char *cond
, *param
;
4044 int trigger
, negate
;
4047 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4049 return bus_log_parse_error(r
);
4051 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4052 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4053 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4054 i
->failed_assert
= cond
;
4055 i
->failed_assert_trigger
= trigger
;
4056 i
->failed_assert_negate
= negate
;
4057 i
->failed_assert_parameter
= param
;
4061 return bus_log_parse_error(r
);
4063 r
= sd_bus_message_exit_container(m
);
4065 return bus_log_parse_error(r
);
4072 case SD_BUS_TYPE_STRUCT_BEGIN
:
4074 if (streq(name
, "LoadError")) {
4075 const char *n
, *message
;
4077 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4079 return bus_log_parse_error(r
);
4081 if (!isempty(message
))
4082 i
->load_error
= message
;
4095 r
= sd_bus_message_skip(m
, contents
);
4097 return bus_log_parse_error(r
);
4102 #define print_prop(name, fmt, ...) \
4105 printf(fmt "\n", __VA_ARGS__); \
4107 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4110 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4116 /* This is a low-level property printer, see
4117 * print_status_info() for the nicer output */
4119 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4120 /* skip what we didn't read */
4121 r
= sd_bus_message_skip(m
, contents
);
4125 switch (contents
[0]) {
4127 case SD_BUS_TYPE_STRUCT_BEGIN
:
4129 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4132 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4134 return bus_log_parse_error(r
);
4137 print_prop(name
, "%"PRIu32
, u
);
4139 print_prop(name
, "%s", "");
4143 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4146 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4148 return bus_log_parse_error(r
);
4150 if (arg_all
|| !isempty(s
))
4151 print_prop(name
, "%s", s
);
4155 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4156 const char *a
= NULL
, *b
= NULL
;
4158 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4160 return bus_log_parse_error(r
);
4162 if (arg_all
|| !isempty(a
) || !isempty(b
))
4163 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4166 } else if (streq_ptr(name
, "SystemCallFilter")) {
4167 _cleanup_strv_free_
char **l
= NULL
;
4170 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4172 return bus_log_parse_error(r
);
4174 r
= sd_bus_message_read(m
, "b", &whitelist
);
4176 return bus_log_parse_error(r
);
4178 r
= sd_bus_message_read_strv(m
, &l
);
4180 return bus_log_parse_error(r
);
4182 r
= sd_bus_message_exit_container(m
);
4184 return bus_log_parse_error(r
);
4186 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4191 fputs(name
, stdout
);
4198 STRV_FOREACH(i
, l
) {
4206 fputc('\n', stdout
);
4214 case SD_BUS_TYPE_ARRAY
:
4216 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4220 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4222 return bus_log_parse_error(r
);
4224 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4225 print_prop("EnvironmentFile", "%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4228 return bus_log_parse_error(r
);
4230 r
= sd_bus_message_exit_container(m
);
4232 return bus_log_parse_error(r
);
4236 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4237 const char *type
, *path
;
4239 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4241 return bus_log_parse_error(r
);
4243 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4244 print_prop(type
, "%s", path
);
4246 return bus_log_parse_error(r
);
4248 r
= sd_bus_message_exit_container(m
);
4250 return bus_log_parse_error(r
);
4254 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4255 const char *type
, *path
;
4257 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4259 return bus_log_parse_error(r
);
4261 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4265 printf("Listen%s=%s\n", type
, path
);
4267 return bus_log_parse_error(r
);
4269 r
= sd_bus_message_exit_container(m
);
4271 return bus_log_parse_error(r
);
4275 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4277 uint64_t value
, next_elapse
;
4279 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4281 return bus_log_parse_error(r
);
4283 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4284 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4286 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4287 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4288 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4291 return bus_log_parse_error(r
);
4293 r
= sd_bus_message_exit_container(m
);
4295 return bus_log_parse_error(r
);
4299 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4300 ExecStatusInfo info
= {};
4302 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4304 return bus_log_parse_error(r
);
4306 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4307 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4308 _cleanup_free_
char *tt
;
4310 tt
= strv_join(info
.argv
, " ");
4313 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4316 yes_no(info
.ignore
),
4317 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4318 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4320 sigchld_code_to_string(info
.code
),
4322 info
.code
== CLD_EXITED
? "" : "/",
4323 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4326 strv_free(info
.argv
);
4330 r
= sd_bus_message_exit_container(m
);
4332 return bus_log_parse_error(r
);
4336 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4337 const char *path
, *rwm
;
4339 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4341 return bus_log_parse_error(r
);
4343 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4344 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4346 return bus_log_parse_error(r
);
4348 r
= sd_bus_message_exit_container(m
);
4350 return bus_log_parse_error(r
);
4354 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4358 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4360 return bus_log_parse_error(r
);
4362 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4363 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4365 return bus_log_parse_error(r
);
4367 r
= sd_bus_message_exit_container(m
);
4369 return bus_log_parse_error(r
);
4373 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4377 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4379 return bus_log_parse_error(r
);
4381 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4382 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4384 return bus_log_parse_error(r
);
4386 r
= sd_bus_message_exit_container(m
);
4388 return bus_log_parse_error(r
);
4396 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4398 return bus_log_parse_error(r
);
4401 r
= sd_bus_message_skip(m
, contents
);
4403 return bus_log_parse_error(r
);
4406 printf("%s=[unprintable]\n", name
);
4412 static int show_one(
4416 bool show_properties
,
4420 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4421 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4422 UnitStatusInfo info
= {
4423 .memory_current
= (uint64_t) -1,
4424 .memory_limit
= (uint64_t) -1,
4425 .cpu_usage_nsec
= (uint64_t) -1,
4426 .tasks_current
= (uint64_t) -1,
4427 .tasks_max
= (uint64_t) -1,
4435 log_debug("Showing one %s", path
);
4437 r
= sd_bus_call_method(
4439 "org.freedesktop.systemd1",
4441 "org.freedesktop.DBus.Properties",
4447 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4449 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4451 return bus_log_parse_error(r
);
4458 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4459 const char *name
, *contents
;
4461 r
= sd_bus_message_read(reply
, "s", &name
);
4463 return bus_log_parse_error(r
);
4465 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4467 return bus_log_parse_error(r
);
4469 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4471 return bus_log_parse_error(r
);
4473 if (show_properties
)
4474 r
= print_property(name
, reply
, contents
);
4476 r
= status_property(name
, reply
, &info
, contents
);
4480 r
= sd_bus_message_exit_container(reply
);
4482 return bus_log_parse_error(r
);
4484 r
= sd_bus_message_exit_container(reply
);
4486 return bus_log_parse_error(r
);
4489 return bus_log_parse_error(r
);
4491 r
= sd_bus_message_exit_container(reply
);
4493 return bus_log_parse_error(r
);
4497 if (!show_properties
) {
4498 if (streq(verb
, "help"))
4499 show_unit_help(&info
);
4501 print_status_info(&info
, ellipsized
);
4504 strv_free(info
.documentation
);
4505 strv_free(info
.dropin_paths
);
4506 strv_free(info
.listen
);
4508 if (!streq_ptr(info
.active_state
, "active") &&
4509 !streq_ptr(info
.active_state
, "reloading") &&
4510 streq(verb
, "status")) {
4511 /* According to LSB: "program not running" */
4512 /* 0: program is running or service is OK
4513 * 1: program is dead and /run PID file exists
4514 * 2: program is dead and /run/lock lock file exists
4515 * 3: program is not running
4516 * 4: program or service status is unknown
4518 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4524 while ((p
= info
.exec
)) {
4525 LIST_REMOVE(exec
, info
.exec
, p
);
4526 exec_status_info_free(p
);
4532 static int get_unit_dbus_path_by_pid(
4537 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4538 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4542 r
= sd_bus_call_method(
4544 "org.freedesktop.systemd1",
4545 "/org/freedesktop/systemd1",
4546 "org.freedesktop.systemd1.Manager",
4552 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4554 r
= sd_bus_message_read(reply
, "o", &u
);
4556 return bus_log_parse_error(r
);
4566 static int show_all(
4569 bool show_properties
,
4573 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4574 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4579 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4583 pager_open(arg_no_pager
, false);
4587 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4589 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4590 _cleanup_free_
char *p
= NULL
;
4592 p
= unit_dbus_path_from_name(u
->id
);
4596 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4599 else if (r
> 0 && ret
== 0)
4606 static int show_system_status(sd_bus
*bus
) {
4607 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4608 _cleanup_free_
char *hn
= NULL
;
4609 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4610 const char *on
, *off
;
4613 hn
= gethostname_malloc();
4617 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4619 return log_error_errno(r
, "Failed to read server status: %m");
4621 if (streq_ptr(mi
.state
, "degraded")) {
4622 on
= ansi_highlight_red();
4623 off
= ansi_normal();
4624 } else if (!streq_ptr(mi
.state
, "running")) {
4625 on
= ansi_highlight_yellow();
4626 off
= ansi_normal();
4630 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4632 printf(" State: %s%s%s\n",
4633 on
, strna(mi
.state
), off
);
4635 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
4636 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
4638 printf(" Since: %s; %s\n",
4639 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4640 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4642 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4643 if (IN_SET(arg_transport
,
4644 BUS_TRANSPORT_LOCAL
,
4645 BUS_TRANSPORT_MACHINE
)) {
4646 static const char prefix
[] = " ";
4650 if (c
> sizeof(prefix
) - 1)
4651 c
-= sizeof(prefix
) - 1;
4655 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4661 static int show(int argc
, char *argv
[], void *userdata
) {
4662 bool show_properties
, show_status
, show_help
, new_line
= false;
4663 bool ellipsized
= false;
4669 show_properties
= streq(argv
[0], "show");
4670 show_status
= streq(argv
[0], "status");
4671 show_help
= streq(argv
[0], "help");
4673 if (show_help
&& argc
<= 1) {
4674 log_error("This command expects one or more unit names. Did you mean --help?");
4678 pager_open(arg_no_pager
, false);
4681 /* Increase max number of open files to 16K if we can, we
4682 * might needs this when browsing journal files, which might
4683 * be split up into many files. */
4684 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4686 r
= acquire_bus(BUS_MANAGER
, &bus
);
4690 /* If no argument is specified inspect the manager itself */
4691 if (show_properties
&& argc
<= 1)
4692 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4694 if (show_status
&& argc
<= 1) {
4696 pager_open(arg_no_pager
, false);
4697 show_system_status(bus
);
4701 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4703 _cleanup_free_
char **patterns
= NULL
;
4706 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4707 _cleanup_free_
char *unit
= NULL
;
4710 if (safe_atou32(*name
, &id
) < 0) {
4711 if (strv_push(&patterns
, *name
) < 0)
4715 } else if (show_properties
) {
4716 /* Interpret as job id */
4717 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4721 /* Interpret as PID */
4722 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4729 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4732 else if (r
> 0 && ret
== 0)
4736 if (!strv_isempty(patterns
)) {
4737 _cleanup_strv_free_
char **names
= NULL
;
4739 r
= expand_names(bus
, patterns
, NULL
, &names
);
4741 return log_error_errno(r
, "Failed to expand names: %m");
4743 STRV_FOREACH(name
, names
) {
4744 _cleanup_free_
char *unit
;
4746 unit
= unit_dbus_path_from_name(*name
);
4750 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4753 else if (r
> 0 && ret
== 0)
4759 if (ellipsized
&& !arg_quiet
)
4760 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
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_lookup_paths_free_ LookupPaths lp
= {};
4784 _cleanup_strv_free_
char **names
= NULL
;
4790 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4791 log_error("Cannot remotely cat units.");
4795 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
4797 return log_error_errno(r
, "Failed to determine unit paths: %m");
4799 r
= acquire_bus(BUS_MANAGER
, &bus
);
4803 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4805 return log_error_errno(r
, "Failed to expand names: %m");
4807 pager_open(arg_no_pager
, false);
4809 STRV_FOREACH(name
, names
) {
4810 _cleanup_free_
char *fragment_path
= NULL
;
4811 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4814 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4825 if (fragment_path
) {
4826 r
= cat_file(fragment_path
, false);
4828 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4831 STRV_FOREACH(path
, dropin_paths
) {
4832 r
= cat_file(*path
, path
== dropin_paths
);
4834 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4841 static int set_property(int argc
, char *argv
[], void *userdata
) {
4842 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4843 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4844 _cleanup_free_
char *n
= NULL
;
4849 polkit_agent_open_if_enabled();
4851 r
= acquire_bus(BUS_MANAGER
, &bus
);
4855 r
= sd_bus_message_new_method_call(
4858 "org.freedesktop.systemd1",
4859 "/org/freedesktop/systemd1",
4860 "org.freedesktop.systemd1.Manager",
4861 "SetUnitProperties");
4863 return bus_log_create_error(r
);
4865 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4867 return log_error_errno(r
, "Failed to mangle unit name: %m");
4869 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4871 return bus_log_create_error(r
);
4873 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4875 return bus_log_create_error(r
);
4877 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4878 r
= bus_append_unit_property_assignment(m
, *i
);
4883 r
= sd_bus_message_close_container(m
);
4885 return bus_log_create_error(r
);
4887 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4889 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4894 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4895 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4900 polkit_agent_open_if_enabled();
4902 r
= acquire_bus(BUS_MANAGER
, &bus
);
4906 if (arg_action
== ACTION_RELOAD
)
4908 else if (arg_action
== ACTION_REEXEC
)
4909 method
= "Reexecute";
4911 assert(arg_action
== ACTION_SYSTEMCTL
);
4914 streq(argv
[0], "clear-jobs") ||
4915 streq(argv
[0], "cancel") ? "ClearJobs" :
4916 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4917 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4918 streq(argv
[0], "halt") ? "Halt" :
4919 streq(argv
[0], "poweroff") ? "PowerOff" :
4920 streq(argv
[0], "reboot") ? "Reboot" :
4921 streq(argv
[0], "kexec") ? "KExec" :
4922 streq(argv
[0], "exit") ? "Exit" :
4923 /* "daemon-reload" */ "Reload";
4926 r
= sd_bus_call_method(
4928 "org.freedesktop.systemd1",
4929 "/org/freedesktop/systemd1",
4930 "org.freedesktop.systemd1.Manager",
4935 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4936 /* There's always a fallback possible for
4937 * legacy actions. */
4939 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4940 /* On reexecution, we expect a disconnect, not a
4944 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
4946 return r
< 0 ? r
: 0;
4949 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4950 _cleanup_strv_free_
char **names
= NULL
;
4956 return daemon_reload(argc
, argv
, userdata
);
4958 polkit_agent_open_if_enabled();
4960 r
= acquire_bus(BUS_MANAGER
, &bus
);
4964 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4966 return log_error_errno(r
, "Failed to expand names: %m");
4968 STRV_FOREACH(name
, names
) {
4969 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4971 q
= sd_bus_call_method(
4973 "org.freedesktop.systemd1",
4974 "/org/freedesktop/systemd1",
4975 "org.freedesktop.systemd1.Manager",
4981 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4990 static int show_environment(int argc
, char *argv
[], void *userdata
) {
4991 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4992 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4997 pager_open(arg_no_pager
, false);
4999 r
= acquire_bus(BUS_MANAGER
, &bus
);
5003 r
= sd_bus_get_property(
5005 "org.freedesktop.systemd1",
5006 "/org/freedesktop/systemd1",
5007 "org.freedesktop.systemd1.Manager",
5013 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5015 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5017 return bus_log_parse_error(r
);
5019 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5022 return bus_log_parse_error(r
);
5024 r
= sd_bus_message_exit_container(reply
);
5026 return bus_log_parse_error(r
);
5031 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5032 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5033 _cleanup_free_
char *cmdline_init
= NULL
;
5034 const char *root
, *init
;
5038 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5039 log_error("Cannot switch root remotely.");
5043 if (argc
< 2 || argc
> 3) {
5044 log_error("Wrong number of arguments.");
5053 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5054 "init", &cmdline_init
,
5057 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5059 init
= cmdline_init
;
5066 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5068 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5069 root_init_path
= strjoina(root
, "/", init
);
5071 /* If the passed init is actually the same as the
5072 * systemd binary, then let's suppress it. */
5073 if (files_same(root_init_path
, root_systemd_path
) > 0)
5077 r
= acquire_bus(BUS_MANAGER
, &bus
);
5081 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5083 r
= sd_bus_call_method(
5085 "org.freedesktop.systemd1",
5086 "/org/freedesktop/systemd1",
5087 "org.freedesktop.systemd1.Manager",
5093 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5098 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5099 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5100 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5108 polkit_agent_open_if_enabled();
5110 r
= acquire_bus(BUS_MANAGER
, &bus
);
5114 method
= streq(argv
[0], "set-environment")
5116 : "UnsetEnvironment";
5118 r
= sd_bus_message_new_method_call(
5121 "org.freedesktop.systemd1",
5122 "/org/freedesktop/systemd1",
5123 "org.freedesktop.systemd1.Manager",
5126 return bus_log_create_error(r
);
5128 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5130 return bus_log_create_error(r
);
5132 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5134 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5139 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5140 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5141 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5145 polkit_agent_open_if_enabled();
5147 r
= acquire_bus(BUS_MANAGER
, &bus
);
5151 r
= sd_bus_message_new_method_call(
5154 "org.freedesktop.systemd1",
5155 "/org/freedesktop/systemd1",
5156 "org.freedesktop.systemd1.Manager",
5159 return bus_log_create_error(r
);
5162 r
= sd_bus_message_append_strv(m
, environ
);
5166 r
= sd_bus_message_open_container(m
, 'a', "s");
5168 return bus_log_create_error(r
);
5170 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5172 if (!env_name_is_valid(*a
)) {
5173 log_error("Not a valid environment variable name: %s", *a
);
5177 STRV_FOREACH(b
, environ
) {
5180 eq
= startswith(*b
, *a
);
5181 if (eq
&& *eq
== '=') {
5183 r
= sd_bus_message_append(m
, "s", *b
);
5185 return bus_log_create_error(r
);
5192 r
= sd_bus_message_close_container(m
);
5195 return bus_log_create_error(r
);
5197 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5199 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5204 static int enable_sysv_units(const char *verb
, char **args
) {
5207 #if defined(HAVE_SYSV_COMPAT)
5208 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5211 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5213 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5216 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5219 if (!STR_IN_SET(verb
,
5225 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5232 const char *argv
[] = {
5233 ROOTLIBEXECDIR
"/systemd-sysv-install",
5240 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5241 bool found_native
= false, found_sysv
;
5250 if (!endswith(name
, ".service"))
5253 if (path_is_absolute(name
))
5256 j
= unit_file_exists(arg_scope
, &paths
, name
);
5257 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5258 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5259 found_native
= j
!= 0;
5261 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5262 * prefer the native unit */
5263 if (found_native
&& streq(verb
, "is-enabled"))
5266 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5270 p
[strlen(p
) - strlen(".service")] = 0;
5271 found_sysv
= access(p
, F_OK
) >= 0;
5276 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5278 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5280 if (!isempty(arg_root
))
5281 argv
[c
++] = q
= strappend("--root=", arg_root
);
5284 argv
[c
++] = basename(p
);
5287 l
= strv_join((char**)argv
, " ");
5291 log_info("Executing: %s", l
);
5295 return log_error_errno(errno
, "Failed to fork: %m");
5296 else if (pid
== 0) {
5299 (void) reset_all_signal_handlers();
5300 (void) reset_signal_mask();
5302 execv(argv
[0], (char**) argv
);
5303 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
5304 _exit(EXIT_FAILURE
);
5307 j
= wait_for_terminate(pid
, &status
);
5309 log_error_errno(j
, "Failed to wait for child: %m");
5313 if (status
.si_code
== CLD_EXITED
) {
5314 if (streq(verb
, "is-enabled")) {
5315 if (status
.si_status
== 0) {
5324 } else if (status
.si_status
!= 0)
5325 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
5327 log_error("Unexpected waitid() result.");
5334 /* Remove this entry, so that we don't try enabling it as native unit */
5337 assert(args
[f
] == name
);
5338 strv_remove(args
, name
);
5345 static int mangle_names(char **original_names
, char ***mangled_names
) {
5346 char **i
, **l
, **name
;
5349 l
= i
= new(char*, strv_length(original_names
) + 1);
5353 STRV_FOREACH(name
, original_names
) {
5355 /* When enabling units qualified path names are OK,
5356 * too, hence allow them explicitly. */
5358 if (is_path(*name
)) {
5365 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5368 return log_error_errno(r
, "Failed to mangle unit name: %m");
5381 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5382 _cleanup_strv_free_
char **names
= NULL
;
5383 const char *verb
= argv
[0];
5384 UnitFileChange
*changes
= NULL
;
5385 unsigned n_changes
= 0;
5386 int carries_install_info
= -1;
5392 r
= mangle_names(strv_skip(argv
, 1), &names
);
5396 r
= enable_sysv_units(verb
, names
);
5400 /* If the operation was fully executed by the SysV compat, let's finish early */
5401 if (strv_isempty(names
))
5404 if (install_client_side()) {
5405 if (streq(verb
, "enable")) {
5406 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5407 carries_install_info
= r
;
5408 } else if (streq(verb
, "disable"))
5409 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5410 else if (streq(verb
, "reenable")) {
5411 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5412 carries_install_info
= r
;
5413 } else if (streq(verb
, "link"))
5414 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5415 else if (streq(verb
, "preset")) {
5416 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5417 carries_install_info
= r
;
5418 } else if (streq(verb
, "mask"))
5419 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5420 else if (streq(verb
, "unmask"))
5421 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5422 else if (streq(verb
, "revert"))
5423 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
5425 assert_not_reached("Unknown verb");
5427 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
5432 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5433 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5434 int expect_carries_install_info
= false;
5435 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
5439 polkit_agent_open_if_enabled();
5441 r
= acquire_bus(BUS_MANAGER
, &bus
);
5445 if (streq(verb
, "enable")) {
5446 method
= "EnableUnitFiles";
5447 expect_carries_install_info
= true;
5448 } else if (streq(verb
, "disable")) {
5449 method
= "DisableUnitFiles";
5451 } else if (streq(verb
, "reenable")) {
5452 method
= "ReenableUnitFiles";
5453 expect_carries_install_info
= true;
5454 } else if (streq(verb
, "link"))
5455 method
= "LinkUnitFiles";
5456 else if (streq(verb
, "preset")) {
5458 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5459 method
= "PresetUnitFilesWithMode";
5460 send_preset_mode
= true;
5462 method
= "PresetUnitFiles";
5464 expect_carries_install_info
= true;
5465 } else if (streq(verb
, "mask"))
5466 method
= "MaskUnitFiles";
5467 else if (streq(verb
, "unmask")) {
5468 method
= "UnmaskUnitFiles";
5470 } else if (streq(verb
, "revert")) {
5471 method
= "RevertUnitFiles";
5472 send_runtime
= send_force
= false;
5474 assert_not_reached("Unknown verb");
5476 r
= sd_bus_message_new_method_call(
5479 "org.freedesktop.systemd1",
5480 "/org/freedesktop/systemd1",
5481 "org.freedesktop.systemd1.Manager",
5484 return bus_log_create_error(r
);
5486 r
= sd_bus_message_append_strv(m
, names
);
5488 return bus_log_create_error(r
);
5490 if (send_preset_mode
) {
5491 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5493 return bus_log_create_error(r
);
5497 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5499 return bus_log_create_error(r
);
5503 r
= sd_bus_message_append(m
, "b", arg_force
);
5505 return bus_log_create_error(r
);
5508 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5510 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
5512 if (expect_carries_install_info
) {
5513 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5515 return bus_log_parse_error(r
);
5518 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5522 /* Try to reload if enabled */
5524 r
= daemon_reload(argc
, argv
, userdata
);
5529 if (carries_install_info
== 0)
5530 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5531 "using systemctl.\n"
5532 "Possible reasons for having this kind of units are:\n"
5533 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5534 " .wants/ or .requires/ directory.\n"
5535 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5536 " a requirement dependency on it.\n"
5537 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5538 " D-Bus, udev, scripted systemctl call, ...).\n");
5540 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5541 char *new_args
[n_changes
+ 2];
5545 r
= acquire_bus(BUS_MANAGER
, &bus
);
5549 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5550 for (i
= 0; i
< n_changes
; i
++)
5551 new_args
[i
+ 1] = basename(changes
[i
].path
);
5552 new_args
[i
+ 1] = NULL
;
5554 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5558 unit_file_changes_free(changes
, n_changes
);
5563 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5564 _cleanup_strv_free_
char **names
= NULL
;
5565 _cleanup_free_
char *target
= NULL
;
5566 const char *verb
= argv
[0];
5573 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5575 return log_error_errno(r
, "Failed to mangle unit name: %m");
5577 r
= mangle_names(strv_skip(argv
, 2), &names
);
5581 if (streq(verb
, "add-wants"))
5583 else if (streq(verb
, "add-requires"))
5584 dep
= UNIT_REQUIRES
;
5586 assert_not_reached("Unknown verb");
5588 if (install_client_side()) {
5589 UnitFileChange
*changes
= NULL
;
5590 unsigned n_changes
= 0;
5592 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5593 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
5594 unit_file_changes_free(changes
, n_changes
);
5597 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5598 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5601 polkit_agent_open_if_enabled();
5603 r
= acquire_bus(BUS_MANAGER
, &bus
);
5607 r
= sd_bus_message_new_method_call(
5610 "org.freedesktop.systemd1",
5611 "/org/freedesktop/systemd1",
5612 "org.freedesktop.systemd1.Manager",
5613 "AddDependencyUnitFiles");
5615 return bus_log_create_error(r
);
5617 r
= sd_bus_message_append_strv(m
, names
);
5619 return bus_log_create_error(r
);
5621 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5623 return bus_log_create_error(r
);
5625 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5627 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
5629 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5635 return daemon_reload(argc
, argv
, userdata
);
5639 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5642 if (install_client_side()) {
5643 UnitFileChange
*changes
= NULL
;
5644 unsigned n_changes
= 0;
5646 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5647 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
5648 unit_file_changes_free(changes
, n_changes
);
5651 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5652 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5655 polkit_agent_open_if_enabled();
5657 r
= acquire_bus(BUS_MANAGER
, &bus
);
5661 r
= sd_bus_call_method(
5663 "org.freedesktop.systemd1",
5664 "/org/freedesktop/systemd1",
5665 "org.freedesktop.systemd1.Manager",
5666 "PresetAllUnitFiles",
5670 unit_file_preset_mode_to_string(arg_preset_mode
),
5674 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
5676 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5682 return daemon_reload(argc
, argv
, userdata
);
5686 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5688 _cleanup_strv_free_
char **names
= NULL
;
5693 r
= mangle_names(strv_skip(argv
, 1), &names
);
5697 r
= enable_sysv_units(argv
[0], names
);
5703 if (install_client_side()) {
5705 STRV_FOREACH(name
, names
) {
5706 UnitFileState state
;
5708 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5710 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5714 UNIT_FILE_ENABLED_RUNTIME
,
5717 UNIT_FILE_GENERATED
))
5721 puts(unit_file_state_to_string(state
));
5725 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5728 r
= acquire_bus(BUS_MANAGER
, &bus
);
5732 STRV_FOREACH(name
, names
) {
5733 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5736 r
= sd_bus_call_method(
5738 "org.freedesktop.systemd1",
5739 "/org/freedesktop/systemd1",
5740 "org.freedesktop.systemd1.Manager",
5746 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5748 r
= sd_bus_message_read(reply
, "s", &s
);
5750 return bus_log_parse_error(r
);
5752 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
5760 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
5763 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5764 _cleanup_free_
char *state
= NULL
;
5768 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5771 return EXIT_FAILURE
;
5774 r
= acquire_bus(BUS_MANAGER
, &bus
);
5778 r
= sd_bus_get_property_string(
5780 "org.freedesktop.systemd1",
5781 "/org/freedesktop/systemd1",
5782 "org.freedesktop.systemd1.Manager",
5795 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5798 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5799 _cleanup_free_
char *t
= NULL
;
5803 assert(original_path
);
5806 r
= tempfn_random(new_path
, NULL
, &t
);
5808 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5810 r
= mkdir_parents(new_path
, 0755);
5812 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5814 r
= copy_file(original_path
, t
, 0, 0644, 0);
5819 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5822 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5830 static int get_file_to_edit(
5831 const LookupPaths
*paths
,
5835 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
5840 path
= strjoin(paths
->persistent_config
, "/", name
, NULL
);
5845 run
= strjoin(paths
->runtime_config
, name
, NULL
);
5851 if (access(path
, F_OK
) >= 0) {
5852 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5866 static int unit_file_create_dropin(
5867 const LookupPaths
*paths
,
5868 const char *unit_name
,
5869 char **ret_new_path
,
5870 char **ret_tmp_path
) {
5872 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5876 assert(ret_new_path
);
5877 assert(ret_tmp_path
);
5879 ending
= strjoina(unit_name
, ".d/override.conf");
5880 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
5884 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5890 *ret_new_path
= tmp_new_path
;
5891 *ret_tmp_path
= tmp_tmp_path
;
5896 static int unit_file_create_copy(
5897 const LookupPaths
*paths
,
5898 const char *unit_name
,
5899 const char *fragment_path
,
5900 char **ret_new_path
,
5901 char **ret_tmp_path
) {
5903 char *tmp_new_path
, *tmp_tmp_path
;
5906 assert(fragment_path
);
5908 assert(ret_new_path
);
5909 assert(ret_tmp_path
);
5911 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
5915 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5918 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5923 if (response
!= 'y') {
5924 log_warning("%s ignored", unit_name
);
5930 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5932 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5937 *ret_new_path
= tmp_new_path
;
5938 *ret_tmp_path
= tmp_tmp_path
;
5943 static int run_editor(char **paths
) {
5951 return log_error_errno(errno
, "Failed to fork: %m");
5955 char *editor
, **editor_args
= NULL
;
5956 char **tmp_path
, **original_path
, *p
;
5957 unsigned n_editor_args
= 0, i
= 1;
5960 (void) reset_all_signal_handlers();
5961 (void) reset_signal_mask();
5963 argc
= strv_length(paths
)/2 + 1;
5965 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5966 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5967 * we try to execute well known editors
5969 editor
= getenv("SYSTEMD_EDITOR");
5971 editor
= getenv("EDITOR");
5973 editor
= getenv("VISUAL");
5975 if (!isempty(editor
)) {
5976 editor_args
= strv_split(editor
, WHITESPACE
);
5979 _exit(EXIT_FAILURE
);
5981 n_editor_args
= strv_length(editor_args
);
5982 argc
+= n_editor_args
- 1;
5984 args
= newa(const char*, argc
+ 1);
5986 if (n_editor_args
> 0) {
5987 args
[0] = editor_args
[0];
5988 for (; i
< n_editor_args
; i
++)
5989 args
[i
] = editor_args
[i
];
5992 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
5993 args
[i
] = *tmp_path
;
5998 if (n_editor_args
> 0)
5999 execvp(args
[0], (char* const*) args
);
6001 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6003 execvp(p
, (char* const*) args
);
6004 /* We do not fail if the editor doesn't exist
6005 * because we want to try each one of them before
6008 if (errno
!= ENOENT
) {
6009 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6010 _exit(EXIT_FAILURE
);
6014 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6015 _exit(EXIT_FAILURE
);
6018 r
= wait_for_terminate_and_warn("editor", pid
, true);
6020 return log_error_errno(r
, "Failed to wait for child: %m");
6025 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6026 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6033 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6037 STRV_FOREACH(name
, names
) {
6038 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
;
6040 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6046 // FIXME: support units with path==NULL (no FragmentPath)
6047 log_error("No fragment exists for %s.", *name
);
6052 r
= unit_file_create_copy(&lp
, *name
, path
, &new_path
, &tmp_path
);
6054 r
= unit_file_create_dropin(&lp
, *name
, &new_path
, &tmp_path
);
6058 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6061 new_path
= tmp_path
= NULL
;
6067 static int edit(int argc
, char *argv
[], void *userdata
) {
6068 _cleanup_strv_free_
char **names
= NULL
;
6069 _cleanup_strv_free_
char **paths
= NULL
;
6070 char **original
, **tmp
;
6075 log_error("Cannot edit units if not on a tty.");
6079 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6080 log_error("Cannot edit units remotely.");
6084 r
= acquire_bus(BUS_MANAGER
, &bus
);
6088 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6090 return log_error_errno(r
, "Failed to expand names: %m");
6092 r
= find_paths_to_edit(bus
, names
, &paths
);
6096 if (strv_isempty(paths
))
6099 r
= run_editor(paths
);
6103 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6104 /* If the temporary file is empty we ignore it. It's
6105 * useful if the user wants to cancel its modification
6107 if (null_or_empty_path(*tmp
)) {
6108 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6112 r
= rename(*tmp
, *original
);
6114 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6121 if (!arg_no_reload
&& !install_client_side())
6122 r
= daemon_reload(argc
, argv
, userdata
);
6125 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6126 (void) unlink(*tmp
);
6128 /* Removing empty dropin dirs */
6130 _cleanup_free_
char *dir
;
6132 dir
= dirname_malloc(*original
);
6136 /* no need to check if the dir is empty, rmdir
6137 * does nothing if it is not the case.
6146 static void systemctl_help(void) {
6148 pager_open(arg_no_pager
, false);
6150 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6151 "Query or send control commands to the systemd manager.\n\n"
6152 " -h --help Show this help\n"
6153 " --version Show package version\n"
6154 " --system Connect to system manager\n"
6155 " --user Connect to user service manager\n"
6156 " -H --host=[USER@]HOST\n"
6157 " Operate on remote host\n"
6158 " -M --machine=CONTAINER\n"
6159 " Operate on local container\n"
6160 " -t --type=TYPE List units of a particular type\n"
6161 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6162 " -p --property=NAME Show only properties by this name\n"
6163 " -a --all Show all loaded units/properties, including dead/empty\n"
6164 " ones. To list all units installed on the system, use\n"
6165 " the 'list-unit-files' command instead.\n"
6166 " -l --full Don't ellipsize unit names on output\n"
6167 " -r --recursive Show unit list of host and local containers\n"
6168 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6169 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6170 " queueing a new job\n"
6171 " --show-types When showing sockets, explicitly show their type\n"
6172 " --value When showing properties, only print the value\n"
6173 " -i --ignore-inhibitors\n"
6174 " When shutting down or sleeping, ignore inhibitors\n"
6175 " --kill-who=WHO Who to send signal to\n"
6176 " -s --signal=SIGNAL Which signal to send\n"
6177 " --now Start or stop unit in addition to enabling or disabling it\n"
6178 " -q --quiet Suppress output\n"
6179 " --no-block Do not wait until operation finished\n"
6180 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6181 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6182 " --no-legend Do not print a legend (column headers and hints)\n"
6183 " --no-pager Do not pipe output into a pager\n"
6184 " --no-ask-password\n"
6185 " Do not ask for system passwords\n"
6186 " --global Enable/disable unit files globally\n"
6187 " --runtime Enable unit files only temporarily until next reboot\n"
6188 " -f --force When enabling unit files, override existing symlinks\n"
6189 " When shutting down, execute action immediately\n"
6190 " --preset-mode= Apply only enable, only disable, or all presets\n"
6191 " --root=PATH Enable unit files in the specified root directory\n"
6192 " -n --lines=INTEGER Number of journal entries to show\n"
6193 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6194 " short-precise, short-monotonic, verbose,\n"
6195 " export, json, json-pretty, json-sse, cat)\n"
6196 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6197 " --plain Print unit dependencies as a list instead of a tree\n\n"
6199 " list-units [PATTERN...] List loaded units\n"
6200 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6201 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6202 " start NAME... Start (activate) one or more units\n"
6203 " stop NAME... Stop (deactivate) one or more units\n"
6204 " reload NAME... Reload one or more units\n"
6205 " restart NAME... Start or restart one or more units\n"
6206 " try-restart NAME... Restart one or more units if active\n"
6207 " reload-or-restart NAME... Reload one or more units if possible,\n"
6208 " otherwise start or restart\n"
6209 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6210 " if supported, otherwise restart\n"
6211 " isolate NAME Start one unit and stop all others\n"
6212 " kill NAME... Send signal to processes of a unit\n"
6213 " is-active PATTERN... Check whether units are active\n"
6214 " is-failed PATTERN... Check whether units are failed\n"
6215 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6216 " show [PATTERN...|JOB...] Show properties of one or more\n"
6217 " units/jobs or the manager\n"
6218 " cat PATTERN... Show files and drop-ins of one or more units\n"
6219 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6220 " help PATTERN...|PID... Show manual for one or more units\n"
6221 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6223 " list-dependencies [NAME] Recursively show units which are required\n"
6224 " or wanted by this unit or by which this\n"
6225 " unit is required or wanted\n\n"
6226 "Unit File Commands:\n"
6227 " list-unit-files [PATTERN...] List installed unit files\n"
6228 " enable NAME... Enable one or more unit files\n"
6229 " disable NAME... Disable one or more unit files\n"
6230 " reenable NAME... Reenable one or more unit files\n"
6231 " preset NAME... Enable/disable one or more unit files\n"
6232 " based on preset configuration\n"
6233 " preset-all Enable/disable all unit files based on\n"
6234 " preset configuration\n"
6235 " is-enabled NAME... Check whether unit files are enabled\n"
6236 " mask NAME... Mask one or more units\n"
6237 " unmask NAME... Unmask one or more units\n"
6238 " link PATH... Link one or more units files into\n"
6239 " the search path\n"
6240 " revert NAME... Revert one or more unit files to vendor\n"
6242 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6243 " on specified one or more units\n"
6244 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6245 " on specified one or more units\n"
6246 " edit NAME... Edit one or more unit files\n"
6247 " get-default Get the name of the default target\n"
6248 " set-default NAME Set the default target\n\n"
6249 "Machine Commands:\n"
6250 " list-machines [PATTERN...] List local containers and host\n\n"
6252 " list-jobs [PATTERN...] List jobs\n"
6253 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6254 "Environment Commands:\n"
6255 " show-environment Dump environment\n"
6256 " set-environment NAME=VALUE... Set one or more environment variables\n"
6257 " unset-environment NAME... Unset one or more environment variables\n"
6258 " import-environment [NAME...] Import all or some environment variables\n\n"
6259 "Manager Lifecycle Commands:\n"
6260 " daemon-reload Reload systemd manager configuration\n"
6261 " daemon-reexec Reexecute systemd manager\n\n"
6262 "System Commands:\n"
6263 " is-system-running Check whether system is fully running\n"
6264 " default Enter system default mode\n"
6265 " rescue Enter system rescue mode\n"
6266 " emergency Enter system emergency mode\n"
6267 " halt Shut down and halt the system\n"
6268 " poweroff Shut down and power-off the system\n"
6269 " reboot [ARG] Shut down and reboot the system\n"
6270 " kexec Shut down and reboot the system with kexec\n"
6271 " exit [EXIT_CODE] Request user instance or container exit\n"
6272 " switch-root ROOT [INIT] Change to a different root file system\n"
6273 " suspend Suspend the system\n"
6274 " hibernate Hibernate the system\n"
6275 " hybrid-sleep Hibernate and suspend the system\n",
6276 program_invocation_short_name
);
6279 static void halt_help(void) {
6280 printf("%s [OPTIONS...]%s\n\n"
6281 "%s the system.\n\n"
6282 " --help Show this help\n"
6283 " --halt Halt the machine\n"
6284 " -p --poweroff Switch off the machine\n"
6285 " --reboot Reboot the machine\n"
6286 " -f --force Force immediate halt/power-off/reboot\n"
6287 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6288 " -d --no-wtmp Don't write wtmp record\n"
6289 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6290 program_invocation_short_name
,
6291 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6292 arg_action
== ACTION_REBOOT
? "Reboot" :
6293 arg_action
== ACTION_POWEROFF
? "Power off" :
6297 static void shutdown_help(void) {
6298 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6299 "Shut down the system.\n\n"
6300 " --help Show this help\n"
6301 " -H --halt Halt the machine\n"
6302 " -P --poweroff Power-off the machine\n"
6303 " -r --reboot Reboot the machine\n"
6304 " -h Equivalent to --poweroff, overridden by --halt\n"
6305 " -k Don't halt/power-off/reboot, just send warnings\n"
6306 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6307 " -c Cancel a pending shutdown\n",
6308 program_invocation_short_name
);
6311 static void telinit_help(void) {
6312 printf("%s [OPTIONS...] {COMMAND}\n\n"
6313 "Send control commands to the init daemon.\n\n"
6314 " --help Show this help\n"
6315 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6317 " 0 Power-off the machine\n"
6318 " 6 Reboot the machine\n"
6319 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6320 " 1, s, S Enter rescue mode\n"
6321 " q, Q Reload init daemon configuration\n"
6322 " u, U Reexecute init daemon\n",
6323 program_invocation_short_name
);
6326 static void runlevel_help(void) {
6327 printf("%s [OPTIONS...]\n\n"
6328 "Prints the previous and current runlevel of the init system.\n\n"
6329 " --help Show this help\n",
6330 program_invocation_short_name
);
6333 static void help_types(void) {
6337 puts("Available unit types:");
6338 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6339 puts(unit_type_to_string(i
));
6342 static void help_states(void) {
6346 puts("Available unit load states:");
6347 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6348 puts(unit_load_state_to_string(i
));
6351 puts("\nAvailable unit active states:");
6352 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6353 puts(unit_active_state_to_string(i
));
6356 puts("\nAvailable automount unit substates:");
6357 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6358 puts(automount_state_to_string(i
));
6361 puts("\nAvailable busname unit substates:");
6362 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6363 puts(busname_state_to_string(i
));
6366 puts("\nAvailable device unit substates:");
6367 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6368 puts(device_state_to_string(i
));
6371 puts("\nAvailable mount unit substates:");
6372 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6373 puts(mount_state_to_string(i
));
6376 puts("\nAvailable path unit substates:");
6377 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6378 puts(path_state_to_string(i
));
6381 puts("\nAvailable scope unit substates:");
6382 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6383 puts(scope_state_to_string(i
));
6386 puts("\nAvailable service unit substates:");
6387 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6388 puts(service_state_to_string(i
));
6391 puts("\nAvailable slice unit substates:");
6392 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6393 puts(slice_state_to_string(i
));
6396 puts("\nAvailable socket unit substates:");
6397 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6398 puts(socket_state_to_string(i
));
6401 puts("\nAvailable swap unit substates:");
6402 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6403 puts(swap_state_to_string(i
));
6406 puts("\nAvailable target unit substates:");
6407 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6408 puts(target_state_to_string(i
));
6411 puts("\nAvailable timer unit substates:");
6412 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6413 puts(timer_state_to_string(i
));
6416 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6425 ARG_IGNORE_DEPENDENCIES
,
6438 ARG_NO_ASK_PASSWORD
,
6451 static const struct option options
[] = {
6452 { "help", no_argument
, NULL
, 'h' },
6453 { "version", no_argument
, NULL
, ARG_VERSION
},
6454 { "type", required_argument
, NULL
, 't' },
6455 { "property", required_argument
, NULL
, 'p' },
6456 { "all", no_argument
, NULL
, 'a' },
6457 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6458 { "after", no_argument
, NULL
, ARG_AFTER
},
6459 { "before", no_argument
, NULL
, ARG_BEFORE
},
6460 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6461 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6462 { "full", no_argument
, NULL
, 'l' },
6463 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6464 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6465 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6466 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6467 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6468 { "value", no_argument
, NULL
, ARG_VALUE
},
6469 { "user", no_argument
, NULL
, ARG_USER
},
6470 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6471 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6472 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6473 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6474 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6475 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6476 { "quiet", no_argument
, NULL
, 'q' },
6477 { "root", required_argument
, NULL
, ARG_ROOT
},
6478 { "force", no_argument
, NULL
, ARG_FORCE
},
6479 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6480 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6481 { "signal", required_argument
, NULL
, 's' },
6482 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6483 { "host", required_argument
, NULL
, 'H' },
6484 { "machine", required_argument
, NULL
, 'M' },
6485 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6486 { "lines", required_argument
, NULL
, 'n' },
6487 { "output", required_argument
, NULL
, 'o' },
6488 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6489 { "state", required_argument
, NULL
, ARG_STATE
},
6490 { "recursive", no_argument
, NULL
, 'r' },
6491 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6492 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6493 { "now", no_argument
, NULL
, ARG_NOW
},
6494 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6504 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6505 arg_ask_password
= true;
6507 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6519 if (isempty(optarg
)) {
6520 log_error("--type requires arguments.");
6526 _cleanup_free_
char *type
= NULL
;
6528 r
= extract_first_word(&p
, &type
, ",", 0);
6530 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6535 if (streq(type
, "help")) {
6540 if (unit_type_from_string(type
) >= 0) {
6541 if (strv_push(&arg_types
, type
) < 0)
6547 /* It's much nicer to use --state= for
6548 * load states, but let's support this
6549 * in --types= too for compatibility
6550 * with old versions */
6551 if (unit_load_state_from_string(type
) >= 0) {
6552 if (strv_push(&arg_states
, type
) < 0)
6558 log_error("Unknown unit type or load state '%s'.", type
);
6559 log_info("Use -t help to see a list of allowed values.");
6567 /* Make sure that if the empty property list
6568 was specified, we won't show any properties. */
6569 if (isempty(optarg
) && !arg_properties
) {
6570 arg_properties
= new0(char*, 1);
6571 if (!arg_properties
)
6576 _cleanup_free_
char *prop
= NULL
;
6578 r
= extract_first_word(&p
, &prop
, ",", 0);
6580 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6585 if (strv_push(&arg_properties
, prop
) < 0)
6592 /* If the user asked for a particular
6593 * property, show it to him, even if it is
6605 arg_dependency
= DEPENDENCY_REVERSE
;
6609 arg_dependency
= DEPENDENCY_AFTER
;
6613 arg_dependency
= DEPENDENCY_BEFORE
;
6616 case ARG_SHOW_TYPES
:
6617 arg_show_types
= true;
6625 arg_job_mode
= optarg
;
6629 arg_job_mode
= "fail";
6632 case ARG_IRREVERSIBLE
:
6633 arg_job_mode
= "replace-irreversibly";
6636 case ARG_IGNORE_DEPENDENCIES
:
6637 arg_job_mode
= "ignore-dependencies";
6641 arg_scope
= UNIT_FILE_USER
;
6645 arg_scope
= UNIT_FILE_SYSTEM
;
6649 arg_scope
= UNIT_FILE_GLOBAL
;
6653 arg_no_block
= true;
6657 arg_no_legend
= true;
6661 arg_no_pager
= true;
6669 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
6679 if (strv_extend(&arg_states
, "failed") < 0)
6697 arg_no_reload
= true;
6701 arg_kill_who
= optarg
;
6705 arg_signal
= signal_from_string_try_harder(optarg
);
6706 if (arg_signal
< 0) {
6707 log_error("Failed to parse signal string %s.", optarg
);
6712 case ARG_NO_ASK_PASSWORD
:
6713 arg_ask_password
= false;
6717 arg_transport
= BUS_TRANSPORT_REMOTE
;
6722 arg_transport
= BUS_TRANSPORT_MACHINE
;
6731 if (safe_atou(optarg
, &arg_lines
) < 0) {
6732 log_error("Failed to parse lines '%s'", optarg
);
6738 arg_output
= output_mode_from_string(optarg
);
6739 if (arg_output
< 0) {
6740 log_error("Unknown output '%s'.", optarg
);
6746 arg_ignore_inhibitors
= true;
6753 case ARG_FIRMWARE_SETUP
:
6754 arg_firmware_setup
= true;
6758 if (isempty(optarg
)) {
6759 log_error("--signal requires arguments.");
6765 _cleanup_free_
char *s
= NULL
;
6767 r
= extract_first_word(&p
, &s
, ",", 0);
6769 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6774 if (streq(s
, "help")) {
6779 if (strv_push(&arg_states
, s
) < 0)
6788 if (geteuid() != 0) {
6789 log_error("--recursive requires root privileges.");
6793 arg_recursive
= true;
6796 case ARG_PRESET_MODE
:
6798 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6799 if (arg_preset_mode
< 0) {
6800 log_error("Failed to parse preset mode: %s.", optarg
);
6811 if (strv_extend(&arg_wall
, optarg
) < 0)
6819 assert_not_reached("Unhandled option");
6822 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6823 log_error("Cannot access user instance remotely.");
6830 static int halt_parse_argv(int argc
, char *argv
[]) {
6839 static const struct option options
[] = {
6840 { "help", no_argument
, NULL
, ARG_HELP
},
6841 { "halt", no_argument
, NULL
, ARG_HALT
},
6842 { "poweroff", no_argument
, NULL
, 'p' },
6843 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6844 { "force", no_argument
, NULL
, 'f' },
6845 { "wtmp-only", no_argument
, NULL
, 'w' },
6846 { "no-wtmp", no_argument
, NULL
, 'd' },
6847 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6856 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6857 if (runlevel
== '0' || runlevel
== '6')
6860 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6868 arg_action
= ACTION_HALT
;
6872 if (arg_action
!= ACTION_REBOOT
)
6873 arg_action
= ACTION_POWEROFF
;
6877 arg_action
= ACTION_REBOOT
;
6899 /* Compatibility nops */
6906 assert_not_reached("Unhandled option");
6909 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6910 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6913 } else if (optind
< argc
) {
6914 log_error("Too many arguments.");
6921 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
6925 if (streq(t
, "now"))
6927 else if (!strchr(t
, ':')) {
6930 if (safe_atou64(t
, &u
) < 0)
6933 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6942 hour
= strtol(t
, &e
, 10);
6943 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6946 minute
= strtol(e
+1, &e
, 10);
6947 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6950 n
= now(CLOCK_REALTIME
);
6951 s
= (time_t) (n
/ USEC_PER_SEC
);
6953 assert_se(localtime_r(&s
, &tm
));
6955 tm
.tm_hour
= (int) hour
;
6956 tm
.tm_min
= (int) minute
;
6959 assert_se(s
= mktime(&tm
));
6961 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6964 *_u
+= USEC_PER_DAY
;
6970 static int shutdown_parse_argv(int argc
, char *argv
[]) {
6977 static const struct option options
[] = {
6978 { "help", no_argument
, NULL
, ARG_HELP
},
6979 { "halt", no_argument
, NULL
, 'H' },
6980 { "poweroff", no_argument
, NULL
, 'P' },
6981 { "reboot", no_argument
, NULL
, 'r' },
6982 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
6983 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6993 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7001 arg_action
= ACTION_HALT
;
7005 arg_action
= ACTION_POWEROFF
;
7010 arg_action
= ACTION_KEXEC
;
7012 arg_action
= ACTION_REBOOT
;
7016 arg_action
= ACTION_KEXEC
;
7020 if (arg_action
!= ACTION_HALT
)
7021 arg_action
= ACTION_POWEROFF
;
7036 /* Compatibility nops */
7040 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7047 assert_not_reached("Unhandled option");
7050 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7051 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7053 log_error("Failed to parse time specification: %s", argv
[optind
]);
7057 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7059 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7060 /* No time argument for shutdown cancel */
7061 wall
= argv
+ optind
;
7062 else if (argc
> optind
+ 1)
7063 /* We skip the time argument */
7064 wall
= argv
+ optind
+ 1;
7067 arg_wall
= strv_copy(wall
);
7077 static int telinit_parse_argv(int argc
, char *argv
[]) {
7084 static const struct option options
[] = {
7085 { "help", no_argument
, NULL
, ARG_HELP
},
7086 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7090 static const struct {
7094 { '0', ACTION_POWEROFF
},
7095 { '6', ACTION_REBOOT
},
7096 { '1', ACTION_RESCUE
},
7097 { '2', ACTION_RUNLEVEL2
},
7098 { '3', ACTION_RUNLEVEL3
},
7099 { '4', ACTION_RUNLEVEL4
},
7100 { '5', ACTION_RUNLEVEL5
},
7101 { 's', ACTION_RESCUE
},
7102 { 'S', ACTION_RESCUE
},
7103 { 'q', ACTION_RELOAD
},
7104 { 'Q', ACTION_RELOAD
},
7105 { 'u', ACTION_REEXEC
},
7106 { 'U', ACTION_REEXEC
}
7115 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7130 assert_not_reached("Unhandled option");
7133 if (optind
>= argc
) {
7134 log_error("%s: required argument missing.", program_invocation_short_name
);
7138 if (optind
+ 1 < argc
) {
7139 log_error("Too many arguments.");
7143 if (strlen(argv
[optind
]) != 1) {
7144 log_error("Expected single character argument.");
7148 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7149 if (table
[i
].from
== argv
[optind
][0])
7152 if (i
>= ELEMENTSOF(table
)) {
7153 log_error("Unknown command '%s'.", argv
[optind
]);
7157 arg_action
= table
[i
].to
;
7164 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7170 static const struct option options
[] = {
7171 { "help", no_argument
, NULL
, ARG_HELP
},
7180 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7191 assert_not_reached("Unhandled option");
7194 if (optind
< argc
) {
7195 log_error("Too many arguments.");
7202 static int parse_argv(int argc
, char *argv
[]) {
7206 if (program_invocation_short_name
) {
7208 if (strstr(program_invocation_short_name
, "halt")) {
7209 arg_action
= ACTION_HALT
;
7210 return halt_parse_argv(argc
, argv
);
7211 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7212 arg_action
= ACTION_POWEROFF
;
7213 return halt_parse_argv(argc
, argv
);
7214 } else if (strstr(program_invocation_short_name
, "reboot")) {
7216 arg_action
= ACTION_KEXEC
;
7218 arg_action
= ACTION_REBOOT
;
7219 return halt_parse_argv(argc
, argv
);
7220 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7221 arg_action
= ACTION_POWEROFF
;
7222 return shutdown_parse_argv(argc
, argv
);
7223 } else if (strstr(program_invocation_short_name
, "init")) {
7225 if (sd_booted() > 0) {
7226 arg_action
= _ACTION_INVALID
;
7227 return telinit_parse_argv(argc
, argv
);
7229 /* Hmm, so some other init system is
7230 * running, we need to forward this
7231 * request to it. For now we simply
7232 * guess that it is Upstart. */
7234 execv(TELINIT
, argv
);
7236 log_error("Couldn't find an alternative telinit implementation to spawn.");
7240 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7241 arg_action
= ACTION_RUNLEVEL
;
7242 return runlevel_parse_argv(argc
, argv
);
7246 arg_action
= ACTION_SYSTEMCTL
;
7247 return systemctl_parse_argv(argc
, argv
);
7250 #ifdef HAVE_SYSV_COMPAT
7251 _pure_
static int action_to_runlevel(void) {
7253 static const char table
[_ACTION_MAX
] = {
7254 [ACTION_HALT
] = '0',
7255 [ACTION_POWEROFF
] = '0',
7256 [ACTION_REBOOT
] = '6',
7257 [ACTION_RUNLEVEL2
] = '2',
7258 [ACTION_RUNLEVEL3
] = '3',
7259 [ACTION_RUNLEVEL4
] = '4',
7260 [ACTION_RUNLEVEL5
] = '5',
7261 [ACTION_RESCUE
] = '1'
7264 assert(arg_action
< _ACTION_MAX
);
7266 return table
[arg_action
];
7270 static int talk_initctl(void) {
7271 #ifdef HAVE_SYSV_COMPAT
7272 struct init_request request
= {
7273 .magic
= INIT_MAGIC
,
7275 .cmd
= INIT_CMD_RUNLVL
7278 _cleanup_close_
int fd
= -1;
7282 rl
= action_to_runlevel();
7286 request
.runlevel
= rl
;
7288 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7290 if (errno
== ENOENT
)
7293 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7296 r
= loop_write(fd
, &request
, sizeof(request
), false);
7298 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7306 static int systemctl_main(int argc
, char *argv
[]) {
7308 static const Verb verbs
[] = {
7309 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7310 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7311 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7312 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7313 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7314 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7315 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7316 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7317 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7318 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7319 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7320 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7321 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7322 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7323 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7324 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7325 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7326 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7327 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7328 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7329 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7330 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7331 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7332 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7333 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7334 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7335 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7336 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7337 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7338 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7339 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7340 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7341 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7342 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7343 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7344 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7345 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7346 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7347 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7348 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7349 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7350 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7351 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7352 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7353 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7354 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7355 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7356 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7357 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7358 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7359 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7360 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7361 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7362 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7363 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7364 { "link", 2, VERB_ANY
, 0, enable_unit
},
7365 { "revert", 2, VERB_ANY
, 0, enable_unit
},
7366 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7367 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7368 { "set-default", 2, 2, 0, set_default
},
7369 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7370 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7371 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7372 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7373 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7374 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7378 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7381 static int reload_with_fallback(void) {
7383 /* First, try systemd via D-Bus. */
7384 if (daemon_reload(0, NULL
, NULL
) >= 0)
7387 /* Nothing else worked, so let's try signals */
7388 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7390 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7391 return log_error_errno(errno
, "kill() failed: %m");
7396 static int start_with_fallback(void) {
7398 /* First, try systemd via D-Bus. */
7399 if (start_unit(0, NULL
, NULL
) >= 0)
7402 /* Nothing else worked, so let's try
7404 if (talk_initctl() > 0)
7407 log_error("Failed to talk to init daemon.");
7411 static int halt_now(enum action a
) {
7414 /* The kernel will automaticall flush ATA disks and suchlike
7415 * on reboot(), but the file systems need to be synce'd
7416 * explicitly in advance. */
7419 /* Make sure C-A-D is handled by the kernel from this point
7421 (void) reboot(RB_ENABLE_CAD
);
7426 log_info("Halting.");
7427 (void) reboot(RB_HALT_SYSTEM
);
7430 case ACTION_POWEROFF
:
7431 log_info("Powering off.");
7432 (void) reboot(RB_POWER_OFF
);
7436 case ACTION_REBOOT
: {
7437 _cleanup_free_
char *param
= NULL
;
7439 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
7441 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
7443 if (!isempty(param
)) {
7444 log_info("Rebooting with argument '%s'.", param
);
7445 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7446 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
7449 log_info("Rebooting.");
7450 (void) reboot(RB_AUTOBOOT
);
7455 assert_not_reached("Unknown action.");
7459 static int logind_schedule_shutdown(void) {
7462 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7463 char date
[FORMAT_TIMESTAMP_MAX
];
7468 (void) logind_set_wall_message();
7470 r
= acquire_bus(BUS_FULL
, &bus
);
7474 switch (arg_action
) {
7478 case ACTION_POWEROFF
:
7479 action
= "poweroff";
7494 action
= strjoina("dry-", action
);
7496 r
= sd_bus_call_method(
7498 "org.freedesktop.login1",
7499 "/org/freedesktop/login1",
7500 "org.freedesktop.login1.Manager",
7508 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7510 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7513 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7518 static int halt_main(void) {
7521 r
= logind_check_inhibitors(arg_action
);
7526 return logind_schedule_shutdown();
7528 if (geteuid() != 0) {
7529 if (arg_dry
|| arg_force
> 0) {
7530 log_error("Must be root.");
7534 /* Try logind if we are a normal user and no special
7535 * mode applies. Maybe PolicyKit allows us to shutdown
7537 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7538 r
= logind_reboot(arg_action
);
7541 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7542 /* requested operation is not
7543 * supported on the local system or
7544 * already in progress */
7546 /* on all other errors, try low-level operation */
7550 if (!arg_dry
&& !arg_force
)
7551 return start_with_fallback();
7553 assert(geteuid() == 0);
7556 if (sd_booted() > 0)
7557 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7559 r
= utmp_put_shutdown();
7561 log_warning_errno(r
, "Failed to write utmp record: %m");
7568 r
= halt_now(arg_action
);
7569 return log_error_errno(r
, "Failed to reboot: %m");
7572 static int runlevel_main(void) {
7573 int r
, runlevel
, previous
;
7575 r
= utmp_get_runlevel(&runlevel
, &previous
);
7582 previous
<= 0 ? 'N' : previous
,
7583 runlevel
<= 0 ? 'N' : runlevel
);
7588 static int logind_cancel_shutdown(void) {
7590 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7594 r
= acquire_bus(BUS_FULL
, &bus
);
7598 (void) logind_set_wall_message();
7600 r
= sd_bus_call_method(
7602 "org.freedesktop.login1",
7603 "/org/freedesktop/login1",
7604 "org.freedesktop.login1.Manager",
7605 "CancelScheduledShutdown",
7609 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7613 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7618 int main(int argc
, char*argv
[]) {
7621 setlocale(LC_ALL
, "");
7622 log_parse_environment();
7625 /* Explicitly not on_tty() to avoid setting cached value.
7626 * This becomes relevant for piping output which might be
7628 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7630 r
= parse_argv(argc
, argv
);
7634 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7635 log_info("Running in chroot, ignoring request.");
7640 /* systemctl_main() will print an error message for the bus
7641 * connection, but only if it needs to */
7643 switch (arg_action
) {
7645 case ACTION_SYSTEMCTL
:
7646 r
= systemctl_main(argc
, argv
);
7650 case ACTION_POWEROFF
:
7656 case ACTION_RUNLEVEL2
:
7657 case ACTION_RUNLEVEL3
:
7658 case ACTION_RUNLEVEL4
:
7659 case ACTION_RUNLEVEL5
:
7661 case ACTION_EMERGENCY
:
7662 case ACTION_DEFAULT
:
7663 r
= start_with_fallback();
7668 r
= reload_with_fallback();
7671 case ACTION_CANCEL_SHUTDOWN
:
7672 r
= logind_cancel_shutdown();
7675 case ACTION_RUNLEVEL
:
7676 r
= runlevel_main();
7679 case _ACTION_INVALID
:
7681 assert_not_reached("Unknown action");
7686 ask_password_agent_close();
7687 polkit_agent_close();
7689 strv_free(arg_types
);
7690 strv_free(arg_states
);
7691 strv_free(arg_properties
);
7693 strv_free(arg_wall
);
7698 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7700 return r
< 0 ? EXIT_FAILURE
: r
;