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 /* Note that '--all' is not purely a state filter, but also a
345 * filter that hides units that "follow" other units (which is
346 * used for device units that appear under different names). */
347 if (!isempty(u
->following
))
350 if (!strv_isempty(arg_states
))
353 /* By default show all units except the ones in inactive
354 * state and with no pending job */
358 if (streq(u
->active_state
, "inactive"))
364 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
365 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
367 unsigned n_shown
= 0;
370 max_id_len
= strlen("UNIT");
371 load_len
= strlen("LOAD");
372 active_len
= strlen("ACTIVE");
373 sub_len
= strlen("SUB");
374 job_len
= strlen("JOB");
377 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
378 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
379 load_len
= MAX(load_len
, strlen(u
->load_state
));
380 active_len
= MAX(active_len
, strlen(u
->active_state
));
381 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
383 if (u
->job_id
!= 0) {
384 job_len
= MAX(job_len
, strlen(u
->job_type
));
388 if (!arg_no_legend
&&
389 (streq(u
->active_state
, "failed") ||
390 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
394 if (!arg_full
&& original_stdout_is_tty
) {
397 id_len
= MIN(max_id_len
, 25u);
398 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
401 basic_len
+= job_len
+ 1;
403 if (basic_len
< (unsigned) columns()) {
404 unsigned extra_len
, incr
;
405 extra_len
= columns() - basic_len
;
407 /* Either UNIT already got 25, or is fully satisfied.
408 * Grant up to 25 to DESC now. */
409 incr
= MIN(extra_len
, 25u);
413 /* split the remaining space between UNIT and DESC,
414 * but do not give UNIT more than it needs. */
416 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
418 desc_len
+= extra_len
- incr
;
424 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
425 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
426 const char *on_loaded
= "", *off_loaded
= "";
427 const char *on_active
= "", *off_active
= "";
428 const char *on_circle
= "", *off_circle
= "";
432 if (!n_shown
&& !arg_no_legend
) {
437 printf("%-*s %-*s %-*s %-*s ",
440 active_len
, "ACTIVE",
444 printf("%-*s ", job_len
, "JOB");
446 if (!arg_full
&& arg_no_pager
)
447 printf("%.*s\n", desc_len
, "DESCRIPTION");
449 printf("%s\n", "DESCRIPTION");
454 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
455 on_loaded
= ansi_highlight_red();
456 on_circle
= ansi_highlight_yellow();
457 off_loaded
= off_circle
= ansi_normal();
459 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
460 on_circle
= on_active
= ansi_highlight_red();
461 off_circle
= off_active
= ansi_normal();
466 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
475 e
= ellipsize(id
, id_len
, 33);
483 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
485 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
486 on_active
, id_len
, id
, off_active
,
487 on_loaded
, load_len
, u
->load_state
, off_loaded
,
488 on_active
, active_len
, u
->active_state
,
489 sub_len
, u
->sub_state
, off_active
,
490 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
493 printf("%.*s\n", desc_len
, u
->description
);
495 printf("%s\n", u
->description
);
498 if (!arg_no_legend
) {
499 const char *on
, *off
;
503 "LOAD = Reflects whether the unit definition was properly loaded.\n"
504 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
505 "SUB = The low-level unit activation state, values depend on unit type.");
506 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
507 on
= ansi_highlight();
510 on
= ansi_highlight_red();
515 printf("%s%u loaded units listed.%s\n"
516 "To show all installed unit files use 'systemctl list-unit-files'.\n",
519 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
520 "To show all installed unit files use 'systemctl list-unit-files'.\n",
527 static int get_unit_list(
531 UnitInfo
**unit_infos
,
533 sd_bus_message
**_reply
) {
535 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
536 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
537 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
546 r
= sd_bus_message_new_method_call(
549 "org.freedesktop.systemd1",
550 "/org/freedesktop/systemd1",
551 "org.freedesktop.systemd1.Manager",
552 "ListUnitsFiltered");
555 return bus_log_create_error(r
);
557 r
= sd_bus_message_append_strv(m
, arg_states
);
559 return bus_log_create_error(r
);
561 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
563 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
565 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
567 return bus_log_parse_error(r
);
569 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
572 if (!output_show_unit(&u
, patterns
))
575 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
578 (*unit_infos
)[c
++] = u
;
581 return bus_log_parse_error(r
);
583 r
= sd_bus_message_exit_container(reply
);
585 return bus_log_parse_error(r
);
593 static void message_set_freep(Set
**set
) {
596 while ((m
= set_steal_first(*set
)))
597 sd_bus_message_unref(m
);
602 static int get_unit_list_recursive(
605 UnitInfo
**_unit_infos
,
609 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
610 _cleanup_(message_set_freep
) Set
*replies
;
611 sd_bus_message
*reply
;
619 replies
= set_new(NULL
);
623 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
627 r
= set_put(replies
, reply
);
629 sd_bus_message_unref(reply
);
634 _cleanup_strv_free_
char **machines
= NULL
;
637 r
= sd_get_machine_names(&machines
);
639 return log_error_errno(r
, "Failed to get machine names: %m");
641 STRV_FOREACH(i
, machines
) {
642 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
645 r
= sd_bus_open_system_machine(&container
, *i
);
647 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
651 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
657 r
= set_put(replies
, reply
);
659 sd_bus_message_unref(reply
);
664 *_machines
= machines
;
669 *_unit_infos
= unit_infos
;
678 static int list_units(int argc
, char *argv
[], void *userdata
) {
679 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
680 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
681 _cleanup_strv_free_
char **machines
= NULL
;
685 pager_open(arg_no_pager
, false);
687 r
= acquire_bus(BUS_MANAGER
, &bus
);
691 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
695 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
696 return output_units_list(unit_infos
, r
);
699 static int get_triggered_units(
704 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
711 r
= sd_bus_get_property_strv(
713 "org.freedesktop.systemd1",
715 "org.freedesktop.systemd1.Unit",
720 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
725 static int get_listening(
727 const char* unit_path
,
730 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
731 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
732 const char *type
, *path
;
735 r
= sd_bus_get_property(
737 "org.freedesktop.systemd1",
739 "org.freedesktop.systemd1.Socket",
745 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
747 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
749 return bus_log_parse_error(r
);
751 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
753 r
= strv_extend(listening
, type
);
757 r
= strv_extend(listening
, path
);
764 return bus_log_parse_error(r
);
766 r
= sd_bus_message_exit_container(reply
);
768 return bus_log_parse_error(r
);
780 /* Note: triggered is a list here, although it almost certainly
781 * will always be one unit. Nevertheless, dbus API allows for multiple
782 * values, so let's follow that. */
785 /* The strv above is shared. free is set only in the first one. */
789 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
795 if (!a
->machine
&& b
->machine
)
797 if (a
->machine
&& !b
->machine
)
799 if (a
->machine
&& b
->machine
) {
800 o
= strcasecmp(a
->machine
, b
->machine
);
805 o
= strcmp(a
->path
, b
->path
);
807 o
= strcmp(a
->type
, b
->type
);
812 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
813 struct socket_info
*s
;
814 unsigned pathlen
= strlen("LISTEN"),
815 typelen
= strlen("TYPE") * arg_show_types
,
816 socklen
= strlen("UNIT"),
817 servlen
= strlen("ACTIVATES");
818 const char *on
, *off
;
820 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
824 socklen
= MAX(socklen
, strlen(s
->id
));
826 typelen
= MAX(typelen
, strlen(s
->type
));
827 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
829 STRV_FOREACH(a
, s
->triggered
)
830 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
831 servlen
= MAX(servlen
, tmp
);
836 printf("%-*s %-*.*s%-*s %s\n",
838 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
842 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
843 _cleanup_free_
char *j
= NULL
;
848 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
856 printf("%-*s %-*s %-*s",
857 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
860 pathlen
, path
, socklen
, s
->id
);
861 STRV_FOREACH(a
, s
->triggered
)
863 a
== s
->triggered
? "" : ",", *a
);
867 on
= ansi_highlight();
872 on
= ansi_highlight_red();
876 if (!arg_no_legend
) {
877 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
879 printf("Pass --all to see loaded but inactive sockets, too.\n");
885 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
886 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
887 _cleanup_strv_free_
char **machines
= NULL
;
888 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
889 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
891 struct socket_info
*s
;
897 pager_open(arg_no_pager
, false);
899 r
= acquire_bus(BUS_MANAGER
, &bus
);
903 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
907 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
908 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
911 if (!endswith(u
->id
, ".socket"))
914 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
918 c
= get_listening(bus
, u
->unit_path
, &listening
);
924 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
929 for (i
= 0; i
< c
; i
++)
930 socket_infos
[cs
+ i
] = (struct socket_info
) {
931 .machine
= u
->machine
,
933 .type
= listening
[i
*2],
934 .path
= listening
[i
*2 + 1],
935 .triggered
= triggered
,
936 .own_triggered
= i
==0,
939 /* from this point on we will cleanup those socket_infos */
942 listening
= triggered
= NULL
; /* avoid cleanup */
945 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
946 (__compar_fn_t
) socket_info_compare
);
948 output_sockets_list(socket_infos
, cs
);
951 assert(cs
== 0 || socket_infos
);
952 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
955 if (s
->own_triggered
)
956 strv_free(s
->triggered
);
962 static int get_next_elapse(
965 dual_timestamp
*next
) {
967 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
975 r
= sd_bus_get_property_trivial(
977 "org.freedesktop.systemd1",
979 "org.freedesktop.systemd1.Timer",
980 "NextElapseUSecMonotonic",
985 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
987 r
= sd_bus_get_property_trivial(
989 "org.freedesktop.systemd1",
991 "org.freedesktop.systemd1.Timer",
992 "NextElapseUSecRealtime",
997 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1003 static int get_last_trigger(
1008 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1015 r
= sd_bus_get_property_trivial(
1017 "org.freedesktop.systemd1",
1019 "org.freedesktop.systemd1.Timer",
1025 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1031 const char* machine
;
1034 usec_t last_trigger
;
1038 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1044 if (!a
->machine
&& b
->machine
)
1046 if (a
->machine
&& !b
->machine
)
1048 if (a
->machine
&& b
->machine
) {
1049 o
= strcasecmp(a
->machine
, b
->machine
);
1054 if (a
->next_elapse
< b
->next_elapse
)
1056 if (a
->next_elapse
> b
->next_elapse
)
1059 return strcmp(a
->id
, b
->id
);
1062 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1063 struct timer_info
*t
;
1065 nextlen
= strlen("NEXT"),
1066 leftlen
= strlen("LEFT"),
1067 lastlen
= strlen("LAST"),
1068 passedlen
= strlen("PASSED"),
1069 unitlen
= strlen("UNIT"),
1070 activatelen
= strlen("ACTIVATES");
1072 const char *on
, *off
;
1074 assert(timer_infos
|| n
== 0);
1076 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1080 if (t
->next_elapse
> 0) {
1081 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1083 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1084 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1086 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1087 leftlen
= MAX(leftlen
, strlen(trel
));
1090 if (t
->last_trigger
> 0) {
1091 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1093 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1094 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1096 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1097 passedlen
= MAX(passedlen
, strlen(trel
));
1100 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1102 STRV_FOREACH(a
, t
->triggered
)
1103 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1105 activatelen
= MAX(activatelen
, ul
);
1110 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1114 passedlen
, "PASSED",
1118 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1119 _cleanup_free_
char *j
= NULL
;
1121 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1122 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1125 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1126 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1128 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1129 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1132 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1139 printf("%-*s %-*s %-*s %-*s %-*s",
1140 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1142 STRV_FOREACH(a
, t
->triggered
)
1144 a
== t
->triggered
? "" : ",", *a
);
1148 on
= ansi_highlight();
1149 off
= ansi_normal();
1153 on
= ansi_highlight_red();
1154 off
= ansi_normal();
1157 if (!arg_no_legend
) {
1158 printf("%s%u timers listed.%s\n", on
, n
, off
);
1160 printf("Pass --all to see loaded but inactive timers, too.\n");
1166 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1172 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1175 if (next
->monotonic
> nw
->monotonic
)
1176 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1178 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1180 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1181 next_elapse
= MIN(converted
, next
->realtime
);
1183 next_elapse
= converted
;
1186 next_elapse
= next
->realtime
;
1191 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1192 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1193 _cleanup_strv_free_
char **machines
= NULL
;
1194 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1195 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1196 struct timer_info
*t
;
1204 pager_open(arg_no_pager
, false);
1206 r
= acquire_bus(BUS_MANAGER
, &bus
);
1210 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1214 dual_timestamp_get(&nw
);
1216 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1217 _cleanup_strv_free_
char **triggered
= NULL
;
1218 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1221 if (!endswith(u
->id
, ".timer"))
1224 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1228 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1232 get_last_trigger(bus
, u
->unit_path
, &last
);
1234 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1239 m
= calc_next_elapse(&nw
, &next
);
1241 timer_infos
[c
++] = (struct timer_info
) {
1242 .machine
= u
->machine
,
1245 .last_trigger
= last
,
1246 .triggered
= triggered
,
1249 triggered
= NULL
; /* avoid cleanup */
1252 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1253 (__compar_fn_t
) timer_info_compare
);
1255 output_timers_list(timer_infos
, c
);
1258 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1259 strv_free(t
->triggered
);
1264 static int compare_unit_file_list(const void *a
, const void *b
) {
1265 const char *d1
, *d2
;
1266 const UnitFileList
*u
= a
, *v
= b
;
1268 d1
= strrchr(u
->path
, '.');
1269 d2
= strrchr(v
->path
, '.');
1274 r
= strcasecmp(d1
, d2
);
1279 return strcasecmp(basename(u
->path
), basename(v
->path
));
1282 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1283 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1286 if (!strv_isempty(arg_types
)) {
1289 dot
= strrchr(u
->path
, '.');
1293 if (!strv_find(arg_types
, dot
+1))
1297 if (!strv_isempty(arg_states
) &&
1298 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1304 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1305 unsigned max_id_len
, id_cols
, state_cols
;
1306 const UnitFileList
*u
;
1308 max_id_len
= strlen("UNIT FILE");
1309 state_cols
= strlen("STATE");
1311 for (u
= units
; u
< units
+ c
; u
++) {
1312 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1313 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1317 unsigned basic_cols
;
1319 id_cols
= MIN(max_id_len
, 25u);
1320 basic_cols
= 1 + id_cols
+ state_cols
;
1321 if (basic_cols
< (unsigned) columns())
1322 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1324 id_cols
= max_id_len
;
1327 printf("%-*s %-*s\n",
1328 id_cols
, "UNIT FILE",
1329 state_cols
, "STATE");
1331 for (u
= units
; u
< units
+ c
; u
++) {
1332 _cleanup_free_
char *e
= NULL
;
1333 const char *on
, *off
;
1336 if (IN_SET(u
->state
,
1338 UNIT_FILE_MASKED_RUNTIME
,
1341 on
= ansi_highlight_red();
1342 off
= ansi_normal();
1343 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1344 on
= ansi_highlight_green();
1345 off
= ansi_normal();
1349 id
= basename(u
->path
);
1351 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1353 printf("%-*s %s%-*s%s\n",
1354 id_cols
, e
? e
: id
,
1355 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1359 printf("\n%u unit files listed.\n", c
);
1362 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1363 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1364 _cleanup_free_ UnitFileList
*units
= NULL
;
1372 pager_open(arg_no_pager
, false);
1374 if (install_client_side()) {
1380 h
= hashmap_new(&string_hash_ops
);
1384 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1386 unit_file_list_free(h
);
1387 return log_error_errno(r
, "Failed to get unit file list: %m");
1390 n_units
= hashmap_size(h
);
1392 units
= new(UnitFileList
, n_units
);
1393 if (!units
&& n_units
> 0) {
1394 unit_file_list_free(h
);
1398 HASHMAP_FOREACH(u
, h
, i
) {
1399 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1406 assert(c
<= n_units
);
1409 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1412 r
= acquire_bus(BUS_MANAGER
, &bus
);
1416 r
= sd_bus_call_method(
1418 "org.freedesktop.systemd1",
1419 "/org/freedesktop/systemd1",
1420 "org.freedesktop.systemd1.Manager",
1426 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1428 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1430 return bus_log_parse_error(r
);
1432 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1434 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1437 units
[c
] = (struct UnitFileList
) {
1439 unit_file_state_from_string(state
)
1442 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1447 return bus_log_parse_error(r
);
1449 r
= sd_bus_message_exit_container(reply
);
1451 return bus_log_parse_error(r
);
1454 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1455 output_unit_file_list(units
, c
);
1457 if (install_client_side()) {
1458 for (unit
= units
; unit
< units
+ c
; unit
++)
1465 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1466 _cleanup_free_
char *n
= NULL
;
1467 size_t max_len
= MAX(columns(),20u);
1473 for (i
= level
- 1; i
>= 0; i
--) {
1475 if (len
> max_len
- 3 && !arg_full
) {
1476 printf("%s...\n",max_len
% 2 ? "" : " ");
1479 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1483 if (len
> max_len
- 3 && !arg_full
) {
1484 printf("%s...\n",max_len
% 2 ? "" : " ");
1488 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1492 printf("%s\n", name
);
1496 n
= ellipsize(name
, max_len
-len
, 100);
1504 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1506 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1507 [DEPENDENCY_FORWARD
] = "Requires\0"
1512 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1517 [DEPENDENCY_AFTER
] = "After\0",
1518 [DEPENDENCY_BEFORE
] = "Before\0",
1521 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1522 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1523 _cleanup_strv_free_
char **ret
= NULL
;
1524 _cleanup_free_
char *path
= NULL
;
1530 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1532 path
= unit_dbus_path_from_name(name
);
1536 r
= sd_bus_call_method(
1538 "org.freedesktop.systemd1",
1540 "org.freedesktop.DBus.Properties",
1544 "s", "org.freedesktop.systemd1.Unit");
1546 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1548 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1550 return bus_log_parse_error(r
);
1552 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1555 r
= sd_bus_message_read(reply
, "s", &prop
);
1557 return bus_log_parse_error(r
);
1559 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1560 r
= sd_bus_message_skip(reply
, "v");
1562 return bus_log_parse_error(r
);
1565 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1567 return bus_log_parse_error(r
);
1569 r
= bus_message_read_strv_extend(reply
, &ret
);
1571 return bus_log_parse_error(r
);
1573 r
= sd_bus_message_exit_container(reply
);
1575 return bus_log_parse_error(r
);
1578 r
= sd_bus_message_exit_container(reply
);
1580 return bus_log_parse_error(r
);
1584 return bus_log_parse_error(r
);
1586 r
= sd_bus_message_exit_container(reply
);
1588 return bus_log_parse_error(r
);
1596 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1597 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1599 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1601 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1604 return strcasecmp(*a
, *b
);
1607 static int list_dependencies_one(
1612 unsigned int branches
) {
1614 _cleanup_strv_free_
char **deps
= NULL
;
1622 r
= strv_extend(units
, name
);
1626 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1630 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1632 STRV_FOREACH(c
, deps
) {
1633 if (strv_contains(*units
, *c
)) {
1635 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1645 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1648 (void) get_state_one_unit(bus
, *c
, &active_state
);
1649 switch (active_state
) {
1651 case UNIT_RELOADING
:
1652 case UNIT_ACTIVATING
:
1653 on
= ansi_highlight_green();
1657 case UNIT_DEACTIVATING
:
1662 on
= ansi_highlight_red();
1666 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1669 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1673 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1674 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1681 strv_remove(*units
, name
);
1686 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1687 _cleanup_strv_free_
char **units
= NULL
;
1688 _cleanup_free_
char *unit
= NULL
;
1694 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1696 return log_error_errno(r
, "Failed to mangle unit name: %m");
1700 u
= SPECIAL_DEFAULT_TARGET
;
1702 pager_open(arg_no_pager
, false);
1704 r
= acquire_bus(BUS_MANAGER
, &bus
);
1710 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1713 struct machine_info
{
1717 char *control_group
;
1718 uint32_t n_failed_units
;
1723 static const struct bus_properties_map machine_info_property_map
[] = {
1724 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1725 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1726 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1727 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1728 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1732 static void machine_info_clear(struct machine_info
*info
) {
1736 free(info
->control_group
);
1741 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1747 for (i
= 0; i
< n
; i
++)
1748 machine_info_clear(&machine_infos
[i
]);
1750 free(machine_infos
);
1753 static int compare_machine_info(const void *a
, const void *b
) {
1754 const struct machine_info
*u
= a
, *v
= b
;
1756 if (u
->is_host
!= v
->is_host
)
1757 return u
->is_host
> v
->is_host
? -1 : 1;
1759 return strcasecmp(u
->name
, v
->name
);
1762 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1763 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1769 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1776 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1783 static bool output_show_machine(const char *name
, char **patterns
) {
1784 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1787 static int get_machine_list(
1789 struct machine_info
**_machine_infos
,
1792 struct machine_info
*machine_infos
= NULL
;
1793 _cleanup_strv_free_
char **m
= NULL
;
1794 _cleanup_free_
char *hn
= NULL
;
1799 hn
= gethostname_malloc();
1803 if (output_show_machine(hn
, patterns
)) {
1804 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1807 machine_infos
[c
].is_host
= true;
1808 machine_infos
[c
].name
= hn
;
1811 get_machine_properties(bus
, &machine_infos
[c
]);
1815 r
= sd_get_machine_names(&m
);
1817 return log_error_errno(r
, "Failed to get machine list: %m");
1819 STRV_FOREACH(i
, m
) {
1820 _cleanup_free_
char *class = NULL
;
1822 if (!output_show_machine(*i
, patterns
))
1825 sd_machine_get_class(*i
, &class);
1826 if (!streq_ptr(class, "container"))
1829 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1830 free_machines_list(machine_infos
, c
);
1834 machine_infos
[c
].is_host
= false;
1835 machine_infos
[c
].name
= strdup(*i
);
1836 if (!machine_infos
[c
].name
) {
1837 free_machines_list(machine_infos
, c
);
1841 get_machine_properties(NULL
, &machine_infos
[c
]);
1845 *_machine_infos
= machine_infos
;
1849 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1850 struct machine_info
*m
;
1853 namelen
= sizeof("NAME") - 1,
1854 statelen
= sizeof("STATE") - 1,
1855 failedlen
= sizeof("FAILED") - 1,
1856 jobslen
= sizeof("JOBS") - 1;
1858 assert(machine_infos
|| n
== 0);
1860 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1861 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1862 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1863 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1864 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1866 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1870 if (!arg_no_legend
) {
1874 printf("%-*s %-*s %-*s %-*s\n",
1877 failedlen
, "FAILED",
1881 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1882 const char *on_state
= "", *off_state
= "";
1883 const char *on_failed
= "", *off_failed
= "";
1884 bool circle
= false;
1886 if (streq_ptr(m
->state
, "degraded")) {
1887 on_state
= ansi_highlight_red();
1888 off_state
= ansi_normal();
1890 } else if (!streq_ptr(m
->state
, "running")) {
1891 on_state
= ansi_highlight_yellow();
1892 off_state
= ansi_normal();
1896 if (m
->n_failed_units
> 0) {
1897 on_failed
= ansi_highlight_red();
1898 off_failed
= ansi_normal();
1900 on_failed
= off_failed
= "";
1903 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1906 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1907 (int) (namelen
- (sizeof(" (host)")-1)), 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
);
1912 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1913 namelen
, strna(m
->name
),
1914 on_state
, statelen
, strna(m
->state
), off_state
,
1915 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1916 jobslen
, m
->n_jobs
);
1920 printf("\n%u machines listed.\n", n
);
1923 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1924 struct machine_info
*machine_infos
= NULL
;
1928 if (geteuid() != 0) {
1929 log_error("Must be root.");
1933 pager_open(arg_no_pager
, false);
1935 r
= acquire_bus(BUS_MANAGER
, &bus
);
1939 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1943 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1944 output_machines_list(machine_infos
, r
);
1945 free_machines_list(machine_infos
, r
);
1950 static int get_default(int argc
, char *argv
[], void *userdata
) {
1951 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1952 _cleanup_free_
char *_path
= NULL
;
1956 if (install_client_side()) {
1957 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1959 return log_error_errno(r
, "Failed to get default target: %m");
1963 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1966 r
= acquire_bus(BUS_MANAGER
, &bus
);
1970 r
= sd_bus_call_method(
1972 "org.freedesktop.systemd1",
1973 "/org/freedesktop/systemd1",
1974 "org.freedesktop.systemd1.Manager",
1980 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1982 r
= sd_bus_message_read(reply
, "s", &path
);
1984 return bus_log_parse_error(r
);
1988 printf("%s\n", path
);
1993 static int set_default(int argc
, char *argv
[], void *userdata
) {
1994 _cleanup_free_
char *unit
= NULL
;
2000 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2002 return log_error_errno(r
, "Failed to mangle unit name: %m");
2004 if (install_client_side()) {
2005 UnitFileChange
*changes
= NULL
;
2006 unsigned n_changes
= 0;
2008 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2009 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2010 unit_file_changes_free(changes
, n_changes
);
2013 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2014 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2017 polkit_agent_open_if_enabled();
2019 r
= acquire_bus(BUS_MANAGER
, &bus
);
2023 r
= sd_bus_call_method(
2025 "org.freedesktop.systemd1",
2026 "/org/freedesktop/systemd1",
2027 "org.freedesktop.systemd1.Manager",
2033 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2035 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2039 /* Try to reload if enabled */
2041 r
= daemon_reload(argc
, argv
, userdata
);
2051 const char *name
, *type
, *state
;
2054 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2055 unsigned id_len
, unit_len
, type_len
, state_len
;
2056 const struct job_info
*j
;
2057 const char *on
, *off
;
2058 bool shorten
= false;
2060 assert(n
== 0 || jobs
);
2063 if (!arg_no_legend
) {
2064 on
= ansi_highlight_green();
2065 off
= ansi_normal();
2067 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2072 pager_open(arg_no_pager
, false);
2074 id_len
= strlen("JOB");
2075 unit_len
= strlen("UNIT");
2076 type_len
= strlen("TYPE");
2077 state_len
= strlen("STATE");
2079 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2080 uint32_t id
= j
->id
;
2081 assert(j
->name
&& j
->type
&& j
->state
);
2083 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2084 unit_len
= MAX(unit_len
, strlen(j
->name
));
2085 type_len
= MAX(type_len
, strlen(j
->type
));
2086 state_len
= MAX(state_len
, strlen(j
->state
));
2089 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2090 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2095 printf("%*s %-*s %-*s %-*s\n",
2099 state_len
, "STATE");
2101 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2102 _cleanup_free_
char *e
= NULL
;
2104 if (streq(j
->state
, "running")) {
2105 on
= ansi_highlight();
2106 off
= ansi_normal();
2110 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2111 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2113 on
, unit_len
, e
? e
: j
->name
, off
,
2115 on
, state_len
, j
->state
, off
);
2118 if (!arg_no_legend
) {
2119 on
= ansi_highlight();
2120 off
= ansi_normal();
2122 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2126 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2127 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2130 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2131 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2132 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2133 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2134 _cleanup_free_
struct job_info
*jobs
= NULL
;
2140 bool skipped
= false;
2142 pager_open(arg_no_pager
, false);
2144 r
= acquire_bus(BUS_MANAGER
, &bus
);
2148 r
= sd_bus_call_method(
2150 "org.freedesktop.systemd1",
2151 "/org/freedesktop/systemd1",
2152 "org.freedesktop.systemd1.Manager",
2158 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2160 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2162 return bus_log_parse_error(r
);
2164 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2165 struct job_info job
= { id
, name
, type
, state
};
2167 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2172 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2178 return bus_log_parse_error(r
);
2180 r
= sd_bus_message_exit_container(reply
);
2182 return bus_log_parse_error(r
);
2184 output_jobs_list(jobs
, c
, skipped
);
2188 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2194 return daemon_reload(argc
, argv
, userdata
);
2196 polkit_agent_open_if_enabled();
2198 r
= acquire_bus(BUS_MANAGER
, &bus
);
2202 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2203 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2207 q
= safe_atou32(*name
, &id
);
2209 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2211 q
= sd_bus_call_method(
2213 "org.freedesktop.systemd1",
2214 "/org/freedesktop/systemd1",
2215 "org.freedesktop.systemd1.Manager",
2221 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2230 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2231 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2235 /* We ignore all errors here, since this is used to show a
2238 /* We don't use unit_dbus_path_from_name() directly since we
2239 * don't want to load the unit if it isn't loaded. */
2241 r
= sd_bus_call_method(
2243 "org.freedesktop.systemd1",
2244 "/org/freedesktop/systemd1",
2245 "org.freedesktop.systemd1.Manager",
2253 r
= sd_bus_message_read(reply
, "o", &path
);
2257 r
= sd_bus_get_property_trivial(
2259 "org.freedesktop.systemd1",
2261 "org.freedesktop.systemd1.Unit",
2271 static void warn_unit_file_changed(const char *name
) {
2272 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2273 ansi_highlight_red(),
2276 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2279 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2286 STRV_FOREACH(p
, lp
->search_path
) {
2287 _cleanup_free_
char *path
;
2289 path
= path_join(arg_root
, *p
, unit_name
);
2293 if (access(path
, F_OK
) == 0) {
2303 static int unit_find_paths(
2305 const char *unit_name
,
2307 char **fragment_path
,
2308 char ***dropin_paths
) {
2310 _cleanup_free_
char *path
= NULL
;
2311 _cleanup_strv_free_
char **dropins
= NULL
;
2315 * Finds where the unit is defined on disk. Returns 0 if the unit
2316 * is not found. Returns 1 if it is found, and sets
2317 * - the path to the unit in *path, if it exists on disk,
2318 * - and a strv of existing drop-ins in *dropins,
2319 * if the arg is not NULL and any dropins were found.
2323 assert(fragment_path
);
2326 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2327 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2328 _cleanup_free_
char *unit
= NULL
;
2330 unit
= unit_dbus_path_from_name(unit_name
);
2334 r
= sd_bus_get_property_string(
2336 "org.freedesktop.systemd1",
2338 "org.freedesktop.systemd1.Unit",
2343 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2346 r
= sd_bus_get_property_strv(
2348 "org.freedesktop.systemd1",
2350 "org.freedesktop.systemd1.Unit",
2355 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2358 _cleanup_set_free_ Set
*names
;
2360 names
= set_new(NULL
);
2364 r
= set_put(names
, unit_name
);
2366 return log_error_errno(r
, "Failed to add unit name: %m");
2368 r
= unit_file_find_path(lp
, unit_name
, &path
);
2373 _cleanup_free_
char *template = NULL
;
2375 r
= unit_name_template(unit_name
, &template);
2376 if (r
< 0 && r
!= -EINVAL
)
2377 return log_error_errno(r
, "Failed to determine template name: %m");
2379 r
= unit_file_find_path(lp
, template, &path
);
2386 r
= unit_file_find_dropin_paths(lp
->search_path
, NULL
, names
, &dropins
);
2394 if (!isempty(path
)) {
2395 *fragment_path
= path
;
2400 if (dropin_paths
&& !strv_isempty(dropins
)) {
2401 *dropin_paths
= dropins
;
2407 log_error("No files found for %s.", unit_name
);
2412 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2413 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2414 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2415 _cleanup_free_
char *buf
= NULL
;
2416 UnitActiveState state
;
2421 assert(active_state
);
2423 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2425 r
= sd_bus_call_method(
2427 "org.freedesktop.systemd1",
2428 "/org/freedesktop/systemd1",
2429 "org.freedesktop.systemd1.Manager",
2435 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2436 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2438 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2439 * considered inactive. */
2440 state
= UNIT_INACTIVE
;
2443 r
= sd_bus_message_read(reply
, "o", &path
);
2445 return bus_log_parse_error(r
);
2447 r
= sd_bus_get_property_string(
2449 "org.freedesktop.systemd1",
2451 "org.freedesktop.systemd1.Unit",
2456 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2458 state
= unit_active_state_from_string(buf
);
2459 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2460 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2465 *active_state
= state
;
2469 static int check_triggering_units(
2473 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2474 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2475 _cleanup_strv_free_
char **triggered_by
= NULL
;
2476 bool print_warning_label
= true;
2477 UnitActiveState active_state
;
2481 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2483 return log_error_errno(r
, "Failed to mangle unit name: %m");
2485 path
= unit_dbus_path_from_name(n
);
2489 r
= sd_bus_get_property_string(
2491 "org.freedesktop.systemd1",
2493 "org.freedesktop.systemd1.Unit",
2498 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2500 if (streq(load_state
, "masked"))
2503 r
= sd_bus_get_property_strv(
2505 "org.freedesktop.systemd1",
2507 "org.freedesktop.systemd1.Unit",
2512 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2514 STRV_FOREACH(i
, triggered_by
) {
2515 r
= get_state_one_unit(bus
, *i
, &active_state
);
2519 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2522 if (print_warning_label
) {
2523 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2524 print_warning_label
= false;
2527 log_warning(" %s", *i
);
2533 static const struct {
2536 } unit_actions
[] = {
2537 { "start", "StartUnit" },
2538 { "stop", "StopUnit" },
2539 { "condstop", "StopUnit" },
2540 { "reload", "ReloadUnit" },
2541 { "restart", "RestartUnit" },
2542 { "try-restart", "TryRestartUnit" },
2543 { "condrestart", "TryRestartUnit" },
2544 { "reload-or-restart", "ReloadOrRestartUnit" },
2545 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2546 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2547 { "condreload", "ReloadOrTryRestartUnit" },
2548 { "force-reload", "ReloadOrTryRestartUnit" }
2551 static const char *verb_to_method(const char *verb
) {
2554 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2555 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2556 return unit_actions
[i
].method
;
2561 static const char *method_to_verb(const char *method
) {
2564 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2565 if (streq_ptr(unit_actions
[i
].method
, method
))
2566 return unit_actions
[i
].verb
;
2571 static int start_unit_one(
2576 sd_bus_error
*error
,
2577 BusWaitForJobs
*w
) {
2579 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2588 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2590 r
= sd_bus_call_method(
2592 "org.freedesktop.systemd1",
2593 "/org/freedesktop/systemd1",
2594 "org.freedesktop.systemd1.Manager",
2602 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2603 /* There's always a fallback possible for
2604 * legacy actions. */
2605 return -EADDRNOTAVAIL
;
2607 verb
= method_to_verb(method
);
2609 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2611 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2612 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2613 log_error("See %s logs and 'systemctl%s status %s' for details.",
2614 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2615 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2621 r
= sd_bus_message_read(reply
, "o", &path
);
2623 return bus_log_parse_error(r
);
2625 if (need_daemon_reload(bus
, name
) > 0)
2626 warn_unit_file_changed(name
);
2629 log_debug("Adding %s to the set", path
);
2630 r
= bus_wait_for_jobs_add(w
, path
);
2638 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2639 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2646 STRV_FOREACH(name
, names
) {
2650 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2652 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2654 return log_error_errno(r
, "Failed to mangle name: %m");
2656 if (string_is_glob(t
))
2657 r
= strv_consume(&globs
, t
);
2659 r
= strv_consume(&mangled
, t
);
2664 /* Query the manager only if any of the names are a glob, since
2665 * this is fairly expensive */
2666 if (!strv_isempty(globs
)) {
2667 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2668 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2669 size_t allocated
, n
;
2671 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2675 n
= strv_length(mangled
);
2678 for (i
= 0; i
< r
; i
++) {
2679 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2682 mangled
[n
] = strdup(unit_infos
[i
].id
);
2686 mangled
[++n
] = NULL
;
2691 mangled
= NULL
; /* do not free */
2696 static const struct {
2700 } action_table
[_ACTION_MAX
] = {
2701 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2702 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2703 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2704 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2705 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2706 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2707 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2708 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2709 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2710 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2711 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2712 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2713 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2714 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2715 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2718 static enum action
verb_to_action(const char *verb
) {
2721 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2722 if (streq_ptr(action_table
[i
].verb
, verb
))
2725 return _ACTION_INVALID
;
2728 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2729 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2730 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2731 _cleanup_strv_free_
char **names
= NULL
;
2736 ask_password_agent_open_if_enabled();
2737 polkit_agent_open_if_enabled();
2739 r
= acquire_bus(BUS_MANAGER
, &bus
);
2743 if (arg_action
== ACTION_SYSTEMCTL
) {
2746 method
= verb_to_method(argv
[0]);
2747 action
= verb_to_action(argv
[0]);
2749 if (streq(argv
[0], "isolate")) {
2753 mode
= action_table
[action
].mode
?: arg_job_mode
;
2755 one_name
= action_table
[action
].target
;
2757 assert(arg_action
< ELEMENTSOF(action_table
));
2758 assert(action_table
[arg_action
].target
);
2760 method
= "StartUnit";
2762 mode
= action_table
[arg_action
].mode
;
2763 one_name
= action_table
[arg_action
].target
;
2767 names
= strv_new(one_name
, NULL
);
2769 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2771 return log_error_errno(r
, "Failed to expand names: %m");
2774 if (!arg_no_block
) {
2775 r
= bus_wait_for_jobs_new(bus
, &w
);
2777 return log_error_errno(r
, "Could not watch jobs: %m");
2780 STRV_FOREACH(name
, names
) {
2781 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2784 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2785 if (r
>= 0 && q
< 0)
2786 r
= translate_bus_error_to_exit_status(q
, &error
);
2789 if (!arg_no_block
) {
2790 int q
, arg_count
= 0;
2791 const char* extra_args
[4] = {};
2793 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2794 extra_args
[arg_count
++] = "--user";
2796 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2797 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2798 extra_args
[arg_count
++] = "-H";
2799 extra_args
[arg_count
++] = arg_host
;
2800 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2801 extra_args
[arg_count
++] = "-M";
2802 extra_args
[arg_count
++] = arg_host
;
2805 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2809 /* When stopping units, warn if they can still be triggered by
2810 * another active unit (socket, path, timer) */
2811 if (!arg_quiet
&& streq(method
, "StopUnit"))
2812 STRV_FOREACH(name
, names
)
2813 check_triggering_units(bus
, *name
);
2819 static int logind_set_wall_message(void) {
2821 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2823 _cleanup_free_
char *m
= NULL
;
2826 r
= acquire_bus(BUS_FULL
, &bus
);
2830 m
= strv_join(arg_wall
, " ");
2834 r
= sd_bus_call_method(
2836 "org.freedesktop.login1",
2837 "/org/freedesktop/login1",
2838 "org.freedesktop.login1.Manager",
2847 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2853 /* Ask systemd-logind, which might grant access to unprivileged users
2854 * through PolicyKit */
2855 static int logind_reboot(enum action a
) {
2857 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2858 const char *method
, *description
;
2862 polkit_agent_open_if_enabled();
2863 (void) logind_set_wall_message();
2865 r
= acquire_bus(BUS_FULL
, &bus
);
2873 description
= "reboot system";
2876 case ACTION_POWEROFF
:
2877 method
= "PowerOff";
2878 description
= "power off system";
2881 case ACTION_SUSPEND
:
2883 description
= "suspend system";
2886 case ACTION_HIBERNATE
:
2887 method
= "Hibernate";
2888 description
= "hibernate system";
2891 case ACTION_HYBRID_SLEEP
:
2892 method
= "HybridSleep";
2893 description
= "put system into hybrid sleep";
2900 r
= sd_bus_call_method(
2902 "org.freedesktop.login1",
2903 "/org/freedesktop/login1",
2904 "org.freedesktop.login1.Manager",
2908 "b", arg_ask_password
);
2910 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2918 static int logind_check_inhibitors(enum action a
) {
2920 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2921 _cleanup_strv_free_
char **sessions
= NULL
;
2922 const char *what
, *who
, *why
, *mode
;
2929 if (arg_ignore_inhibitors
|| arg_force
> 0)
2941 r
= acquire_bus(BUS_FULL
, &bus
);
2945 r
= sd_bus_call_method(
2947 "org.freedesktop.login1",
2948 "/org/freedesktop/login1",
2949 "org.freedesktop.login1.Manager",
2955 /* If logind is not around, then there are no inhibitors... */
2958 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2960 return bus_log_parse_error(r
);
2962 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2963 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2964 _cleanup_strv_free_
char **sv
= NULL
;
2966 if (!streq(mode
, "block"))
2969 sv
= strv_split(what
, ":");
2973 if ((pid_t
) pid
< 0)
2974 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2976 if (!strv_contains(sv
,
2981 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2984 get_process_comm(pid
, &comm
);
2985 user
= uid_to_name(uid
);
2987 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2988 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2993 return bus_log_parse_error(r
);
2995 r
= sd_bus_message_exit_container(reply
);
2997 return bus_log_parse_error(r
);
2999 /* Check for current sessions */
3000 sd_get_sessions(&sessions
);
3001 STRV_FOREACH(s
, sessions
) {
3002 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3004 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3007 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3010 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3013 sd_session_get_tty(*s
, &tty
);
3014 sd_session_get_seat(*s
, &seat
);
3015 sd_session_get_service(*s
, &service
);
3016 user
= uid_to_name(uid
);
3018 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3025 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3026 action_table
[a
].verb
);
3034 static int logind_prepare_firmware_setup(void) {
3036 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3040 r
= acquire_bus(BUS_FULL
, &bus
);
3044 r
= sd_bus_call_method(
3046 "org.freedesktop.login1",
3047 "/org/freedesktop/login1",
3048 "org.freedesktop.login1.Manager",
3049 "SetRebootToFirmwareSetup",
3054 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3058 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3063 static int prepare_firmware_setup(void) {
3066 if (!arg_firmware_setup
)
3069 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3071 r
= efi_set_reboot_to_firmware(true);
3073 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3078 return logind_prepare_firmware_setup();
3081 static int set_exit_code(uint8_t code
) {
3082 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3086 r
= acquire_bus(BUS_MANAGER
, &bus
);
3090 r
= sd_bus_call_method(
3092 "org.freedesktop.systemd1",
3093 "/org/freedesktop/systemd1",
3094 "org.freedesktop.systemd1.Manager",
3100 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3105 static int start_special(int argc
, char *argv
[], void *userdata
) {
3111 a
= verb_to_action(argv
[0]);
3113 r
= logind_check_inhibitors(a
);
3117 if (arg_force
>= 2 && geteuid() != 0) {
3118 log_error("Must be root.");
3122 r
= prepare_firmware_setup();
3126 if (a
== ACTION_REBOOT
&& argc
> 1) {
3127 r
= update_reboot_parameter_and_warn(argv
[1]);
3131 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3134 /* If the exit code is not given on the command line,
3135 * don't reset it to zero: just keep it as it might
3136 * have been set previously. */
3138 r
= safe_atou8(argv
[1], &code
);
3140 return log_error_errno(r
, "Invalid exit code.");
3142 r
= set_exit_code(code
);
3147 if (arg_force
>= 2 &&
3154 if (arg_force
>= 1 &&
3161 return daemon_reload(argc
, argv
, userdata
);
3163 /* First try logind, to allow authentication with polkit */
3169 ACTION_HYBRID_SLEEP
)) {
3170 r
= logind_reboot(a
);
3173 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3174 /* requested operation is not supported or already in progress */
3177 /* On all other errors, try low-level operation */
3180 return start_unit(argc
, argv
, userdata
);
3183 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3184 _cleanup_strv_free_
char **names
= NULL
;
3185 UnitActiveState active_state
;
3191 r
= acquire_bus(BUS_MANAGER
, &bus
);
3195 r
= expand_names(bus
, args
, NULL
, &names
);
3197 return log_error_errno(r
, "Failed to expand names: %m");
3199 STRV_FOREACH(name
, names
) {
3200 r
= get_state_one_unit(bus
, *name
, &active_state
);
3205 puts(unit_active_state_to_string(active_state
));
3207 for (i
= 0; i
< nb_states
; ++i
)
3208 if (good_states
[i
] == active_state
)
3212 /* use the given return code for the case that we won't find
3213 * any unit which matches the list */
3214 return found
? 0 : code
;
3217 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3218 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3219 /* According to LSB: 3, "program is not running" */
3220 return check_unit_generic(3, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3223 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3224 const UnitActiveState states
[] = { UNIT_FAILED
};
3225 return check_unit_generic(1, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3228 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3229 _cleanup_strv_free_
char **names
= NULL
;
3230 char *kill_who
= NULL
, **name
;
3234 polkit_agent_open_if_enabled();
3236 r
= acquire_bus(BUS_MANAGER
, &bus
);
3241 arg_kill_who
= "all";
3243 /* --fail was specified */
3244 if (streq(arg_job_mode
, "fail"))
3245 kill_who
= strjoina(arg_kill_who
, "-fail");
3247 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3249 return log_error_errno(r
, "Failed to expand names: %m");
3251 STRV_FOREACH(name
, names
) {
3252 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3254 q
= sd_bus_call_method(
3256 "org.freedesktop.systemd1",
3257 "/org/freedesktop/systemd1",
3258 "org.freedesktop.systemd1.Manager",
3262 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3264 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3273 typedef struct ExecStatusInfo
{
3281 usec_t start_timestamp
;
3282 usec_t exit_timestamp
;
3287 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3290 static void exec_status_info_free(ExecStatusInfo
*i
) {
3299 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3300 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3303 int32_t code
, status
;
3309 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3311 return bus_log_parse_error(r
);
3315 r
= sd_bus_message_read(m
, "s", &path
);
3317 return bus_log_parse_error(r
);
3319 i
->path
= strdup(path
);
3323 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3325 return bus_log_parse_error(r
);
3327 r
= sd_bus_message_read(m
,
3330 &start_timestamp
, &start_timestamp_monotonic
,
3331 &exit_timestamp
, &exit_timestamp_monotonic
,
3335 return bus_log_parse_error(r
);
3338 i
->start_timestamp
= (usec_t
) start_timestamp
;
3339 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3340 i
->pid
= (pid_t
) pid
;
3344 r
= sd_bus_message_exit_container(m
);
3346 return bus_log_parse_error(r
);
3351 typedef struct UnitStatusInfo
{
3353 const char *load_state
;
3354 const char *active_state
;
3355 const char *sub_state
;
3356 const char *unit_file_state
;
3357 const char *unit_file_preset
;
3359 const char *description
;
3360 const char *following
;
3362 char **documentation
;
3364 const char *fragment_path
;
3365 const char *source_path
;
3366 const char *control_group
;
3368 char **dropin_paths
;
3370 const char *load_error
;
3373 usec_t inactive_exit_timestamp
;
3374 usec_t inactive_exit_timestamp_monotonic
;
3375 usec_t active_enter_timestamp
;
3376 usec_t active_exit_timestamp
;
3377 usec_t inactive_enter_timestamp
;
3379 bool need_daemon_reload
;
3385 const char *status_text
;
3386 const char *pid_file
;
3390 usec_t start_timestamp
;
3391 usec_t exit_timestamp
;
3393 int exit_code
, exit_status
;
3395 usec_t condition_timestamp
;
3396 bool condition_result
;
3397 bool failed_condition_trigger
;
3398 bool failed_condition_negate
;
3399 const char *failed_condition
;
3400 const char *failed_condition_parameter
;
3402 usec_t assert_timestamp
;
3404 bool failed_assert_trigger
;
3405 bool failed_assert_negate
;
3406 const char *failed_assert
;
3407 const char *failed_assert_parameter
;
3410 unsigned n_accepted
;
3411 unsigned n_connections
;
3414 /* Pairs of type, path */
3418 const char *sysfs_path
;
3420 /* Mount, Automount */
3427 uint64_t memory_current
;
3428 uint64_t memory_limit
;
3429 uint64_t cpu_usage_nsec
;
3430 uint64_t tasks_current
;
3433 LIST_HEAD(ExecStatusInfo
, exec
);
3436 static void print_status_info(
3441 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3443 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3444 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3450 /* This shows pretty information about a unit. See
3451 * print_property() for a low-level property printer */
3453 if (streq_ptr(i
->active_state
, "failed")) {
3454 active_on
= ansi_highlight_red();
3455 active_off
= ansi_normal();
3456 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3457 active_on
= ansi_highlight_green();
3458 active_off
= ansi_normal();
3460 active_on
= active_off
= "";
3462 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3464 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3465 printf(" - %s", i
->description
);
3470 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3472 if (streq_ptr(i
->load_state
, "error")) {
3473 on
= ansi_highlight_red();
3474 off
= ansi_normal();
3478 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3480 if (i
->load_error
!= 0)
3481 printf(" Loaded: %s%s%s (Reason: %s)\n",
3482 on
, strna(i
->load_state
), off
, i
->load_error
);
3483 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3484 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3485 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3486 else if (path
&& !isempty(i
->unit_file_state
))
3487 printf(" Loaded: %s%s%s (%s; %s)\n",
3488 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3490 printf(" Loaded: %s%s%s (%s)\n",
3491 on
, strna(i
->load_state
), off
, path
);
3493 printf(" Loaded: %s%s%s\n",
3494 on
, strna(i
->load_state
), off
);
3497 printf("Transient: yes\n");
3499 if (!strv_isempty(i
->dropin_paths
)) {
3500 _cleanup_free_
char *dir
= NULL
;
3504 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3505 if (! dir
|| last
) {
3506 printf(dir
? " " : " Drop-In: ");
3510 dir
= dirname_malloc(*dropin
);
3516 printf("%s\n %s", dir
,
3517 draw_special_char(DRAW_TREE_RIGHT
));
3520 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3522 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3526 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3528 printf(" Active: %s%s (%s)%s",
3529 active_on
, strna(i
->active_state
), ss
, active_off
);
3531 printf(" Active: %s%s%s",
3532 active_on
, strna(i
->active_state
), active_off
);
3534 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3535 printf(" (Result: %s)", i
->result
);
3537 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3538 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3539 (streq_ptr(i
->active_state
, "inactive") ||
3540 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3541 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3542 i
->active_exit_timestamp
;
3544 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3545 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3548 printf(" since %s; %s\n", s2
, s1
);
3550 printf(" since %s\n", s2
);
3554 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3555 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3556 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3558 printf("Condition: start %scondition failed%s at %s%s%s\n",
3559 ansi_highlight_yellow(), ansi_normal(),
3560 s2
, s1
? "; " : "", strempty(s1
));
3561 if (i
->failed_condition_trigger
)
3562 printf(" none of the trigger conditions were met\n");
3563 else if (i
->failed_condition
)
3564 printf(" %s=%s%s was not met\n",
3565 i
->failed_condition
,
3566 i
->failed_condition_negate
? "!" : "",
3567 i
->failed_condition_parameter
);
3570 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3571 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3572 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3574 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3575 ansi_highlight_red(), ansi_normal(),
3576 s2
, s1
? "; " : "", strempty(s1
));
3577 if (i
->failed_assert_trigger
)
3578 printf(" none of the trigger assertions were met\n");
3579 else if (i
->failed_assert
)
3580 printf(" %s=%s%s was not met\n",
3582 i
->failed_assert_negate
? "!" : "",
3583 i
->failed_assert_parameter
);
3587 printf(" Device: %s\n", i
->sysfs_path
);
3589 printf(" Where: %s\n", i
->where
);
3591 printf(" What: %s\n", i
->what
);
3593 STRV_FOREACH(t
, i
->documentation
)
3594 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3596 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3597 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3600 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3602 LIST_FOREACH(exec
, p
, i
->exec
) {
3603 _cleanup_free_
char *argv
= NULL
;
3606 /* Only show exited processes here */
3610 argv
= strv_join(p
->argv
, " ");
3611 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3613 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3615 on
= ansi_highlight_red();
3616 off
= ansi_normal();
3620 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3622 if (p
->code
== CLD_EXITED
) {
3625 printf("status=%i", p
->status
);
3627 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3632 printf("signal=%s", signal_to_string(p
->status
));
3634 printf(")%s\n", off
);
3636 if (i
->main_pid
== p
->pid
&&
3637 i
->start_timestamp
== p
->start_timestamp
&&
3638 i
->exit_timestamp
== p
->start_timestamp
)
3639 /* Let's not show this twice */
3642 if (p
->pid
== i
->control_pid
)
3646 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3647 if (i
->main_pid
> 0) {
3648 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3651 _cleanup_free_
char *comm
= NULL
;
3652 get_process_comm(i
->main_pid
, &comm
);
3654 printf(" (%s)", comm
);
3655 } else if (i
->exit_code
> 0) {
3656 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3658 if (i
->exit_code
== CLD_EXITED
) {
3661 printf("status=%i", i
->exit_status
);
3663 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3668 printf("signal=%s", signal_to_string(i
->exit_status
));
3672 if (i
->control_pid
> 0)
3676 if (i
->control_pid
> 0) {
3677 _cleanup_free_
char *c
= NULL
;
3679 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3681 get_process_comm(i
->control_pid
, &c
);
3690 printf(" Status: \"%s\"\n", i
->status_text
);
3691 if (i
->status_errno
> 0)
3692 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3694 if (i
->tasks_current
!= (uint64_t) -1) {
3695 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3697 if (i
->tasks_max
!= (uint64_t) -1)
3698 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3703 if (i
->memory_current
!= (uint64_t) -1) {
3704 char buf
[FORMAT_BYTES_MAX
];
3706 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3708 if (i
->memory_limit
!= (uint64_t) -1)
3709 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3714 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3715 char buf
[FORMAT_TIMESPAN_MAX
];
3716 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3719 if (i
->control_group
&&
3720 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3721 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3724 printf(" CGroup: %s\n", i
->control_group
);
3726 if (IN_SET(arg_transport
,
3727 BUS_TRANSPORT_LOCAL
,
3728 BUS_TRANSPORT_MACHINE
)) {
3731 static const char prefix
[] = " ";
3734 if (c
> sizeof(prefix
) - 1)
3735 c
-= sizeof(prefix
) - 1;
3739 if (i
->main_pid
> 0)
3740 extra
[k
++] = i
->main_pid
;
3742 if (i
->control_pid
> 0)
3743 extra
[k
++] = i
->control_pid
;
3745 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3749 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3750 show_journal_by_unit(
3755 i
->inactive_exit_timestamp_monotonic
,
3758 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3759 SD_JOURNAL_LOCAL_ONLY
,
3760 arg_scope
== UNIT_FILE_SYSTEM
,
3763 if (i
->need_daemon_reload
)
3764 warn_unit_file_changed(i
->id
);
3767 static void show_unit_help(UnitStatusInfo
*i
) {
3772 if (!i
->documentation
) {
3773 log_info("Documentation for %s not known.", i
->id
);
3777 STRV_FOREACH(p
, i
->documentation
)
3778 if (startswith(*p
, "man:"))
3779 show_man_page(*p
+ 4, false);
3781 log_info("Can't show: %s", *p
);
3784 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3791 switch (contents
[0]) {
3793 case SD_BUS_TYPE_STRING
: {
3796 r
= sd_bus_message_read(m
, "s", &s
);
3798 return bus_log_parse_error(r
);
3801 if (streq(name
, "Id"))
3803 else if (streq(name
, "LoadState"))
3805 else if (streq(name
, "ActiveState"))
3806 i
->active_state
= s
;
3807 else if (streq(name
, "SubState"))
3809 else if (streq(name
, "Description"))
3811 else if (streq(name
, "FragmentPath"))
3812 i
->fragment_path
= s
;
3813 else if (streq(name
, "SourcePath"))
3816 else if (streq(name
, "DefaultControlGroup")) {
3818 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3820 i
->control_group
= e
;
3823 else if (streq(name
, "ControlGroup"))
3824 i
->control_group
= s
;
3825 else if (streq(name
, "StatusText"))
3827 else if (streq(name
, "PIDFile"))
3829 else if (streq(name
, "SysFSPath"))
3831 else if (streq(name
, "Where"))
3833 else if (streq(name
, "What"))
3835 else if (streq(name
, "Following"))
3837 else if (streq(name
, "UnitFileState"))
3838 i
->unit_file_state
= s
;
3839 else if (streq(name
, "UnitFilePreset"))
3840 i
->unit_file_preset
= s
;
3841 else if (streq(name
, "Result"))
3848 case SD_BUS_TYPE_BOOLEAN
: {
3851 r
= sd_bus_message_read(m
, "b", &b
);
3853 return bus_log_parse_error(r
);
3855 if (streq(name
, "Accept"))
3857 else if (streq(name
, "NeedDaemonReload"))
3858 i
->need_daemon_reload
= b
;
3859 else if (streq(name
, "ConditionResult"))
3860 i
->condition_result
= b
;
3861 else if (streq(name
, "AssertResult"))
3862 i
->assert_result
= b
;
3863 else if (streq(name
, "Transient"))
3869 case SD_BUS_TYPE_UINT32
: {
3872 r
= sd_bus_message_read(m
, "u", &u
);
3874 return bus_log_parse_error(r
);
3876 if (streq(name
, "MainPID")) {
3878 i
->main_pid
= (pid_t
) u
;
3881 } else if (streq(name
, "ControlPID"))
3882 i
->control_pid
= (pid_t
) u
;
3883 else if (streq(name
, "ExecMainPID")) {
3885 i
->main_pid
= (pid_t
) u
;
3886 } else if (streq(name
, "NAccepted"))
3888 else if (streq(name
, "NConnections"))
3889 i
->n_connections
= u
;
3894 case SD_BUS_TYPE_INT32
: {
3897 r
= sd_bus_message_read(m
, "i", &j
);
3899 return bus_log_parse_error(r
);
3901 if (streq(name
, "ExecMainCode"))
3902 i
->exit_code
= (int) j
;
3903 else if (streq(name
, "ExecMainStatus"))
3904 i
->exit_status
= (int) j
;
3905 else if (streq(name
, "StatusErrno"))
3906 i
->status_errno
= (int) j
;
3911 case SD_BUS_TYPE_UINT64
: {
3914 r
= sd_bus_message_read(m
, "t", &u
);
3916 return bus_log_parse_error(r
);
3918 if (streq(name
, "ExecMainStartTimestamp"))
3919 i
->start_timestamp
= (usec_t
) u
;
3920 else if (streq(name
, "ExecMainExitTimestamp"))
3921 i
->exit_timestamp
= (usec_t
) u
;
3922 else if (streq(name
, "ActiveEnterTimestamp"))
3923 i
->active_enter_timestamp
= (usec_t
) u
;
3924 else if (streq(name
, "InactiveEnterTimestamp"))
3925 i
->inactive_enter_timestamp
= (usec_t
) u
;
3926 else if (streq(name
, "InactiveExitTimestamp"))
3927 i
->inactive_exit_timestamp
= (usec_t
) u
;
3928 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3929 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3930 else if (streq(name
, "ActiveExitTimestamp"))
3931 i
->active_exit_timestamp
= (usec_t
) u
;
3932 else if (streq(name
, "ConditionTimestamp"))
3933 i
->condition_timestamp
= (usec_t
) u
;
3934 else if (streq(name
, "AssertTimestamp"))
3935 i
->assert_timestamp
= (usec_t
) u
;
3936 else if (streq(name
, "MemoryCurrent"))
3937 i
->memory_current
= u
;
3938 else if (streq(name
, "MemoryLimit"))
3939 i
->memory_limit
= u
;
3940 else if (streq(name
, "TasksCurrent"))
3941 i
->tasks_current
= u
;
3942 else if (streq(name
, "TasksMax"))
3944 else if (streq(name
, "CPUUsageNSec"))
3945 i
->cpu_usage_nsec
= u
;
3950 case SD_BUS_TYPE_ARRAY
:
3952 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3953 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3955 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3957 return bus_log_parse_error(r
);
3959 info
= new0(ExecStatusInfo
, 1);
3963 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3965 info
->name
= strdup(name
);
3969 LIST_PREPEND(exec
, i
->exec
, info
);
3971 info
= new0(ExecStatusInfo
, 1);
3977 return bus_log_parse_error(r
);
3979 r
= sd_bus_message_exit_container(m
);
3981 return bus_log_parse_error(r
);
3985 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3986 const char *type
, *path
;
3988 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3990 return bus_log_parse_error(r
);
3992 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3994 r
= strv_extend(&i
->listen
, type
);
3998 r
= strv_extend(&i
->listen
, path
);
4003 return bus_log_parse_error(r
);
4005 r
= sd_bus_message_exit_container(m
);
4007 return bus_log_parse_error(r
);
4011 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4013 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4015 return bus_log_parse_error(r
);
4017 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4019 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4021 return bus_log_parse_error(r
);
4023 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4024 const char *cond
, *param
;
4025 int trigger
, negate
;
4028 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4030 return bus_log_parse_error(r
);
4032 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4033 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4034 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4035 i
->failed_condition
= cond
;
4036 i
->failed_condition_trigger
= trigger
;
4037 i
->failed_condition_negate
= negate
;
4038 i
->failed_condition_parameter
= param
;
4042 return bus_log_parse_error(r
);
4044 r
= sd_bus_message_exit_container(m
);
4046 return bus_log_parse_error(r
);
4048 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4049 const char *cond
, *param
;
4050 int trigger
, negate
;
4053 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4055 return bus_log_parse_error(r
);
4057 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4058 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4059 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4060 i
->failed_assert
= cond
;
4061 i
->failed_assert_trigger
= trigger
;
4062 i
->failed_assert_negate
= negate
;
4063 i
->failed_assert_parameter
= param
;
4067 return bus_log_parse_error(r
);
4069 r
= sd_bus_message_exit_container(m
);
4071 return bus_log_parse_error(r
);
4078 case SD_BUS_TYPE_STRUCT_BEGIN
:
4080 if (streq(name
, "LoadError")) {
4081 const char *n
, *message
;
4083 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4085 return bus_log_parse_error(r
);
4087 if (!isempty(message
))
4088 i
->load_error
= message
;
4101 r
= sd_bus_message_skip(m
, contents
);
4103 return bus_log_parse_error(r
);
4108 #define print_prop(name, fmt, ...) \
4111 printf(fmt "\n", __VA_ARGS__); \
4113 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4116 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4122 /* This is a low-level property printer, see
4123 * print_status_info() for the nicer output */
4125 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4126 /* skip what we didn't read */
4127 r
= sd_bus_message_skip(m
, contents
);
4131 switch (contents
[0]) {
4133 case SD_BUS_TYPE_STRUCT_BEGIN
:
4135 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4138 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4140 return bus_log_parse_error(r
);
4143 print_prop(name
, "%"PRIu32
, u
);
4145 print_prop(name
, "%s", "");
4149 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4152 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4154 return bus_log_parse_error(r
);
4156 if (arg_all
|| !isempty(s
))
4157 print_prop(name
, "%s", s
);
4161 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4162 const char *a
= NULL
, *b
= NULL
;
4164 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4166 return bus_log_parse_error(r
);
4168 if (arg_all
|| !isempty(a
) || !isempty(b
))
4169 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4172 } else if (streq_ptr(name
, "SystemCallFilter")) {
4173 _cleanup_strv_free_
char **l
= NULL
;
4176 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4178 return bus_log_parse_error(r
);
4180 r
= sd_bus_message_read(m
, "b", &whitelist
);
4182 return bus_log_parse_error(r
);
4184 r
= sd_bus_message_read_strv(m
, &l
);
4186 return bus_log_parse_error(r
);
4188 r
= sd_bus_message_exit_container(m
);
4190 return bus_log_parse_error(r
);
4192 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4197 fputs(name
, stdout
);
4204 STRV_FOREACH(i
, l
) {
4212 fputc('\n', stdout
);
4220 case SD_BUS_TYPE_ARRAY
:
4222 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4226 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4228 return bus_log_parse_error(r
);
4230 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4231 print_prop("EnvironmentFile", "%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4234 return bus_log_parse_error(r
);
4236 r
= sd_bus_message_exit_container(m
);
4238 return bus_log_parse_error(r
);
4242 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4243 const char *type
, *path
;
4245 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4247 return bus_log_parse_error(r
);
4249 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4250 print_prop(type
, "%s", path
);
4252 return bus_log_parse_error(r
);
4254 r
= sd_bus_message_exit_container(m
);
4256 return bus_log_parse_error(r
);
4260 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4261 const char *type
, *path
;
4263 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4265 return bus_log_parse_error(r
);
4267 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4271 printf("Listen%s=%s\n", type
, path
);
4273 return bus_log_parse_error(r
);
4275 r
= sd_bus_message_exit_container(m
);
4277 return bus_log_parse_error(r
);
4281 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4283 uint64_t value
, next_elapse
;
4285 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4287 return bus_log_parse_error(r
);
4289 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4290 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4292 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4293 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4294 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4297 return bus_log_parse_error(r
);
4299 r
= sd_bus_message_exit_container(m
);
4301 return bus_log_parse_error(r
);
4305 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4306 ExecStatusInfo info
= {};
4308 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4310 return bus_log_parse_error(r
);
4312 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4313 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4314 _cleanup_free_
char *tt
;
4316 tt
= strv_join(info
.argv
, " ");
4319 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4322 yes_no(info
.ignore
),
4323 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4324 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4326 sigchld_code_to_string(info
.code
),
4328 info
.code
== CLD_EXITED
? "" : "/",
4329 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4332 strv_free(info
.argv
);
4336 r
= sd_bus_message_exit_container(m
);
4338 return bus_log_parse_error(r
);
4342 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4343 const char *path
, *rwm
;
4345 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4347 return bus_log_parse_error(r
);
4349 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4350 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4352 return bus_log_parse_error(r
);
4354 r
= sd_bus_message_exit_container(m
);
4356 return bus_log_parse_error(r
);
4360 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4364 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4366 return bus_log_parse_error(r
);
4368 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4369 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4371 return bus_log_parse_error(r
);
4373 r
= sd_bus_message_exit_container(m
);
4375 return bus_log_parse_error(r
);
4379 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4383 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4385 return bus_log_parse_error(r
);
4387 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4388 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4390 return bus_log_parse_error(r
);
4392 r
= sd_bus_message_exit_container(m
);
4394 return bus_log_parse_error(r
);
4402 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4404 return bus_log_parse_error(r
);
4407 r
= sd_bus_message_skip(m
, contents
);
4409 return bus_log_parse_error(r
);
4412 printf("%s=[unprintable]\n", name
);
4418 static int show_one(
4422 bool show_properties
,
4426 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4427 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4428 UnitStatusInfo info
= {
4429 .memory_current
= (uint64_t) -1,
4430 .memory_limit
= (uint64_t) -1,
4431 .cpu_usage_nsec
= (uint64_t) -1,
4432 .tasks_current
= (uint64_t) -1,
4433 .tasks_max
= (uint64_t) -1,
4441 log_debug("Showing one %s", path
);
4443 r
= sd_bus_call_method(
4445 "org.freedesktop.systemd1",
4447 "org.freedesktop.DBus.Properties",
4453 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4455 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4457 return bus_log_parse_error(r
);
4464 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4465 const char *name
, *contents
;
4467 r
= sd_bus_message_read(reply
, "s", &name
);
4469 return bus_log_parse_error(r
);
4471 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4473 return bus_log_parse_error(r
);
4475 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4477 return bus_log_parse_error(r
);
4479 if (show_properties
)
4480 r
= print_property(name
, reply
, contents
);
4482 r
= status_property(name
, reply
, &info
, contents
);
4486 r
= sd_bus_message_exit_container(reply
);
4488 return bus_log_parse_error(r
);
4490 r
= sd_bus_message_exit_container(reply
);
4492 return bus_log_parse_error(r
);
4495 return bus_log_parse_error(r
);
4497 r
= sd_bus_message_exit_container(reply
);
4499 return bus_log_parse_error(r
);
4503 if (!show_properties
) {
4504 if (streq(verb
, "help"))
4505 show_unit_help(&info
);
4507 print_status_info(&info
, ellipsized
);
4510 strv_free(info
.documentation
);
4511 strv_free(info
.dropin_paths
);
4512 strv_free(info
.listen
);
4514 if (!streq_ptr(info
.active_state
, "active") &&
4515 !streq_ptr(info
.active_state
, "reloading") &&
4516 streq(verb
, "status")) {
4517 /* According to LSB: "program not running" */
4518 /* 0: program is running or service is OK
4519 * 1: program is dead and /run PID file exists
4520 * 2: program is dead and /run/lock lock file exists
4521 * 3: program is not running
4522 * 4: program or service status is unknown
4524 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4530 while ((p
= info
.exec
)) {
4531 LIST_REMOVE(exec
, info
.exec
, p
);
4532 exec_status_info_free(p
);
4538 static int get_unit_dbus_path_by_pid(
4543 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4544 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4548 r
= sd_bus_call_method(
4550 "org.freedesktop.systemd1",
4551 "/org/freedesktop/systemd1",
4552 "org.freedesktop.systemd1.Manager",
4558 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4560 r
= sd_bus_message_read(reply
, "o", &u
);
4562 return bus_log_parse_error(r
);
4572 static int show_all(
4575 bool show_properties
,
4579 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4580 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4585 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4589 pager_open(arg_no_pager
, false);
4593 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4595 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4596 _cleanup_free_
char *p
= NULL
;
4598 p
= unit_dbus_path_from_name(u
->id
);
4602 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4605 else if (r
> 0 && ret
== 0)
4612 static int show_system_status(sd_bus
*bus
) {
4613 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4614 _cleanup_free_
char *hn
= NULL
;
4615 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4616 const char *on
, *off
;
4619 hn
= gethostname_malloc();
4623 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4625 return log_error_errno(r
, "Failed to read server status: %m");
4627 if (streq_ptr(mi
.state
, "degraded")) {
4628 on
= ansi_highlight_red();
4629 off
= ansi_normal();
4630 } else if (!streq_ptr(mi
.state
, "running")) {
4631 on
= ansi_highlight_yellow();
4632 off
= ansi_normal();
4636 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4638 printf(" State: %s%s%s\n",
4639 on
, strna(mi
.state
), off
);
4641 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
4642 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
4644 printf(" Since: %s; %s\n",
4645 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4646 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4648 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4649 if (IN_SET(arg_transport
,
4650 BUS_TRANSPORT_LOCAL
,
4651 BUS_TRANSPORT_MACHINE
)) {
4652 static const char prefix
[] = " ";
4656 if (c
> sizeof(prefix
) - 1)
4657 c
-= sizeof(prefix
) - 1;
4661 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4667 static int show(int argc
, char *argv
[], void *userdata
) {
4668 bool show_properties
, show_status
, show_help
, new_line
= false;
4669 bool ellipsized
= false;
4675 show_properties
= streq(argv
[0], "show");
4676 show_status
= streq(argv
[0], "status");
4677 show_help
= streq(argv
[0], "help");
4679 if (show_help
&& argc
<= 1) {
4680 log_error("This command expects one or more unit names. Did you mean --help?");
4684 pager_open(arg_no_pager
, false);
4687 /* Increase max number of open files to 16K if we can, we
4688 * might needs this when browsing journal files, which might
4689 * be split up into many files. */
4690 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4692 r
= acquire_bus(BUS_MANAGER
, &bus
);
4696 /* If no argument is specified inspect the manager itself */
4697 if (show_properties
&& argc
<= 1)
4698 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4700 if (show_status
&& argc
<= 1) {
4702 pager_open(arg_no_pager
, false);
4703 show_system_status(bus
);
4707 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4709 _cleanup_free_
char **patterns
= NULL
;
4712 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4713 _cleanup_free_
char *unit
= NULL
;
4716 if (safe_atou32(*name
, &id
) < 0) {
4717 if (strv_push(&patterns
, *name
) < 0)
4721 } else if (show_properties
) {
4722 /* Interpret as job id */
4723 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4727 /* Interpret as PID */
4728 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4735 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4738 else if (r
> 0 && ret
== 0)
4742 if (!strv_isempty(patterns
)) {
4743 _cleanup_strv_free_
char **names
= NULL
;
4745 r
= expand_names(bus
, patterns
, NULL
, &names
);
4747 return log_error_errno(r
, "Failed to expand names: %m");
4749 STRV_FOREACH(name
, names
) {
4750 _cleanup_free_
char *unit
;
4752 unit
= unit_dbus_path_from_name(*name
);
4756 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4759 else if (r
> 0 && ret
== 0)
4765 if (ellipsized
&& !arg_quiet
)
4766 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4771 static int cat_file(const char *filename
, bool newline
) {
4772 _cleanup_close_
int fd
;
4774 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4778 printf("%s%s# %s%s\n",
4779 newline
? "\n" : "",
4780 ansi_highlight_blue(),
4785 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4788 static int cat(int argc
, char *argv
[], void *userdata
) {
4789 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4790 _cleanup_strv_free_
char **names
= NULL
;
4796 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4797 log_error("Cannot remotely cat units.");
4801 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
4803 return log_error_errno(r
, "Failed to determine unit paths: %m");
4805 r
= acquire_bus(BUS_MANAGER
, &bus
);
4809 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4811 return log_error_errno(r
, "Failed to expand names: %m");
4813 pager_open(arg_no_pager
, false);
4815 STRV_FOREACH(name
, names
) {
4816 _cleanup_free_
char *fragment_path
= NULL
;
4817 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4820 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4831 if (fragment_path
) {
4832 r
= cat_file(fragment_path
, false);
4834 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4837 STRV_FOREACH(path
, dropin_paths
) {
4838 r
= cat_file(*path
, path
== dropin_paths
);
4840 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4847 static int set_property(int argc
, char *argv
[], void *userdata
) {
4848 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4849 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4850 _cleanup_free_
char *n
= NULL
;
4855 polkit_agent_open_if_enabled();
4857 r
= acquire_bus(BUS_MANAGER
, &bus
);
4861 r
= sd_bus_message_new_method_call(
4864 "org.freedesktop.systemd1",
4865 "/org/freedesktop/systemd1",
4866 "org.freedesktop.systemd1.Manager",
4867 "SetUnitProperties");
4869 return bus_log_create_error(r
);
4871 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4873 return log_error_errno(r
, "Failed to mangle unit name: %m");
4875 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4877 return bus_log_create_error(r
);
4879 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4881 return bus_log_create_error(r
);
4883 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4884 r
= bus_append_unit_property_assignment(m
, *i
);
4889 r
= sd_bus_message_close_container(m
);
4891 return bus_log_create_error(r
);
4893 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4895 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4900 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4901 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4906 polkit_agent_open_if_enabled();
4908 r
= acquire_bus(BUS_MANAGER
, &bus
);
4912 if (arg_action
== ACTION_RELOAD
)
4914 else if (arg_action
== ACTION_REEXEC
)
4915 method
= "Reexecute";
4917 assert(arg_action
== ACTION_SYSTEMCTL
);
4920 streq(argv
[0], "clear-jobs") ||
4921 streq(argv
[0], "cancel") ? "ClearJobs" :
4922 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4923 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4924 streq(argv
[0], "halt") ? "Halt" :
4925 streq(argv
[0], "poweroff") ? "PowerOff" :
4926 streq(argv
[0], "reboot") ? "Reboot" :
4927 streq(argv
[0], "kexec") ? "KExec" :
4928 streq(argv
[0], "exit") ? "Exit" :
4929 /* "daemon-reload" */ "Reload";
4932 r
= sd_bus_call_method(
4934 "org.freedesktop.systemd1",
4935 "/org/freedesktop/systemd1",
4936 "org.freedesktop.systemd1.Manager",
4941 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4942 /* There's always a fallback possible for
4943 * legacy actions. */
4945 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4946 /* On reexecution, we expect a disconnect, not a
4950 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
4952 return r
< 0 ? r
: 0;
4955 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4956 _cleanup_strv_free_
char **names
= NULL
;
4962 return daemon_reload(argc
, argv
, userdata
);
4964 polkit_agent_open_if_enabled();
4966 r
= acquire_bus(BUS_MANAGER
, &bus
);
4970 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4972 return log_error_errno(r
, "Failed to expand names: %m");
4974 STRV_FOREACH(name
, names
) {
4975 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4977 q
= sd_bus_call_method(
4979 "org.freedesktop.systemd1",
4980 "/org/freedesktop/systemd1",
4981 "org.freedesktop.systemd1.Manager",
4987 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4996 static int show_environment(int argc
, char *argv
[], void *userdata
) {
4997 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4998 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5003 pager_open(arg_no_pager
, false);
5005 r
= acquire_bus(BUS_MANAGER
, &bus
);
5009 r
= sd_bus_get_property(
5011 "org.freedesktop.systemd1",
5012 "/org/freedesktop/systemd1",
5013 "org.freedesktop.systemd1.Manager",
5019 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5021 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5023 return bus_log_parse_error(r
);
5025 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5028 return bus_log_parse_error(r
);
5030 r
= sd_bus_message_exit_container(reply
);
5032 return bus_log_parse_error(r
);
5037 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5038 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5039 _cleanup_free_
char *cmdline_init
= NULL
;
5040 const char *root
, *init
;
5044 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5045 log_error("Cannot switch root remotely.");
5049 if (argc
< 2 || argc
> 3) {
5050 log_error("Wrong number of arguments.");
5059 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5060 "init", &cmdline_init
,
5063 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5065 init
= cmdline_init
;
5072 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5074 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5075 root_init_path
= strjoina(root
, "/", init
);
5077 /* If the passed init is actually the same as the
5078 * systemd binary, then let's suppress it. */
5079 if (files_same(root_init_path
, root_systemd_path
) > 0)
5083 r
= acquire_bus(BUS_MANAGER
, &bus
);
5087 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5089 r
= sd_bus_call_method(
5091 "org.freedesktop.systemd1",
5092 "/org/freedesktop/systemd1",
5093 "org.freedesktop.systemd1.Manager",
5099 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5104 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5105 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5106 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5114 polkit_agent_open_if_enabled();
5116 r
= acquire_bus(BUS_MANAGER
, &bus
);
5120 method
= streq(argv
[0], "set-environment")
5122 : "UnsetEnvironment";
5124 r
= sd_bus_message_new_method_call(
5127 "org.freedesktop.systemd1",
5128 "/org/freedesktop/systemd1",
5129 "org.freedesktop.systemd1.Manager",
5132 return bus_log_create_error(r
);
5134 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5136 return bus_log_create_error(r
);
5138 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5140 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5145 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5146 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5147 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5151 polkit_agent_open_if_enabled();
5153 r
= acquire_bus(BUS_MANAGER
, &bus
);
5157 r
= sd_bus_message_new_method_call(
5160 "org.freedesktop.systemd1",
5161 "/org/freedesktop/systemd1",
5162 "org.freedesktop.systemd1.Manager",
5165 return bus_log_create_error(r
);
5168 r
= sd_bus_message_append_strv(m
, environ
);
5172 r
= sd_bus_message_open_container(m
, 'a', "s");
5174 return bus_log_create_error(r
);
5176 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5178 if (!env_name_is_valid(*a
)) {
5179 log_error("Not a valid environment variable name: %s", *a
);
5183 STRV_FOREACH(b
, environ
) {
5186 eq
= startswith(*b
, *a
);
5187 if (eq
&& *eq
== '=') {
5189 r
= sd_bus_message_append(m
, "s", *b
);
5191 return bus_log_create_error(r
);
5198 r
= sd_bus_message_close_container(m
);
5201 return bus_log_create_error(r
);
5203 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5205 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5210 static int enable_sysv_units(const char *verb
, char **args
) {
5213 #if defined(HAVE_SYSV_COMPAT)
5214 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5217 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5219 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5222 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5225 if (!STR_IN_SET(verb
,
5231 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5238 const char *argv
[] = {
5239 ROOTLIBEXECDIR
"/systemd-sysv-install",
5246 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5247 bool found_native
= false, found_sysv
;
5256 if (!endswith(name
, ".service"))
5259 if (path_is_absolute(name
))
5262 j
= unit_file_exists(arg_scope
, &paths
, name
);
5263 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5264 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5265 found_native
= j
!= 0;
5267 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5268 * prefer the native unit */
5269 if (found_native
&& streq(verb
, "is-enabled"))
5272 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5276 p
[strlen(p
) - strlen(".service")] = 0;
5277 found_sysv
= access(p
, F_OK
) >= 0;
5282 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5284 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5286 if (!isempty(arg_root
))
5287 argv
[c
++] = q
= strappend("--root=", arg_root
);
5290 argv
[c
++] = basename(p
);
5293 l
= strv_join((char**)argv
, " ");
5297 log_info("Executing: %s", l
);
5301 return log_error_errno(errno
, "Failed to fork: %m");
5302 else if (pid
== 0) {
5305 (void) reset_all_signal_handlers();
5306 (void) reset_signal_mask();
5308 execv(argv
[0], (char**) argv
);
5309 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
5310 _exit(EXIT_FAILURE
);
5313 j
= wait_for_terminate(pid
, &status
);
5315 log_error_errno(j
, "Failed to wait for child: %m");
5319 if (status
.si_code
== CLD_EXITED
) {
5320 if (streq(verb
, "is-enabled")) {
5321 if (status
.si_status
== 0) {
5330 } else if (status
.si_status
!= 0)
5331 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
5333 log_error("Unexpected waitid() result.");
5340 /* Remove this entry, so that we don't try enabling it as native unit */
5343 assert(args
[f
] == name
);
5344 strv_remove(args
, name
);
5351 static int mangle_names(char **original_names
, char ***mangled_names
) {
5352 char **i
, **l
, **name
;
5355 l
= i
= new(char*, strv_length(original_names
) + 1);
5359 STRV_FOREACH(name
, original_names
) {
5361 /* When enabling units qualified path names are OK,
5362 * too, hence allow them explicitly. */
5364 if (is_path(*name
)) {
5371 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5374 return log_error_errno(r
, "Failed to mangle unit name: %m");
5387 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5388 _cleanup_strv_free_
char **names
= NULL
;
5389 const char *verb
= argv
[0];
5390 UnitFileChange
*changes
= NULL
;
5391 unsigned n_changes
= 0;
5392 int carries_install_info
= -1;
5398 r
= mangle_names(strv_skip(argv
, 1), &names
);
5402 r
= enable_sysv_units(verb
, names
);
5406 /* If the operation was fully executed by the SysV compat, let's finish early */
5407 if (strv_isempty(names
))
5410 if (install_client_side()) {
5411 if (streq(verb
, "enable")) {
5412 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5413 carries_install_info
= r
;
5414 } else if (streq(verb
, "disable"))
5415 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5416 else if (streq(verb
, "reenable")) {
5417 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5418 carries_install_info
= r
;
5419 } else if (streq(verb
, "link"))
5420 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5421 else if (streq(verb
, "preset")) {
5422 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5423 carries_install_info
= r
;
5424 } else if (streq(verb
, "mask"))
5425 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5426 else if (streq(verb
, "unmask"))
5427 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5428 else if (streq(verb
, "revert"))
5429 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
5431 assert_not_reached("Unknown verb");
5433 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
5438 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5439 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5440 int expect_carries_install_info
= false;
5441 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
5445 polkit_agent_open_if_enabled();
5447 r
= acquire_bus(BUS_MANAGER
, &bus
);
5451 if (streq(verb
, "enable")) {
5452 method
= "EnableUnitFiles";
5453 expect_carries_install_info
= true;
5454 } else if (streq(verb
, "disable")) {
5455 method
= "DisableUnitFiles";
5457 } else if (streq(verb
, "reenable")) {
5458 method
= "ReenableUnitFiles";
5459 expect_carries_install_info
= true;
5460 } else if (streq(verb
, "link"))
5461 method
= "LinkUnitFiles";
5462 else if (streq(verb
, "preset")) {
5464 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5465 method
= "PresetUnitFilesWithMode";
5466 send_preset_mode
= true;
5468 method
= "PresetUnitFiles";
5470 expect_carries_install_info
= true;
5471 } else if (streq(verb
, "mask"))
5472 method
= "MaskUnitFiles";
5473 else if (streq(verb
, "unmask")) {
5474 method
= "UnmaskUnitFiles";
5476 } else if (streq(verb
, "revert")) {
5477 method
= "RevertUnitFiles";
5478 send_runtime
= send_force
= false;
5480 assert_not_reached("Unknown verb");
5482 r
= sd_bus_message_new_method_call(
5485 "org.freedesktop.systemd1",
5486 "/org/freedesktop/systemd1",
5487 "org.freedesktop.systemd1.Manager",
5490 return bus_log_create_error(r
);
5492 r
= sd_bus_message_append_strv(m
, names
);
5494 return bus_log_create_error(r
);
5496 if (send_preset_mode
) {
5497 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5499 return bus_log_create_error(r
);
5503 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5505 return bus_log_create_error(r
);
5509 r
= sd_bus_message_append(m
, "b", arg_force
);
5511 return bus_log_create_error(r
);
5514 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5516 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
5518 if (expect_carries_install_info
) {
5519 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5521 return bus_log_parse_error(r
);
5524 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5528 /* Try to reload if enabled */
5530 r
= daemon_reload(argc
, argv
, userdata
);
5535 if (carries_install_info
== 0)
5536 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
5537 "settings in the [Install] section, and DefaultInstance for template units).\n"
5538 "This means they are not meant to be enabled using systemctl.\n"
5539 "Possible reasons for having this kind of units are:\n"
5540 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5541 " .wants/ or .requires/ directory.\n"
5542 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5543 " a requirement dependency on it.\n"
5544 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5545 " D-Bus, udev, scripted systemctl call, ...).\n"
5546 "4) In case of template units, the unit is meant to be enabled with some\n"
5547 " instance name specified.");
5549 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5550 char *new_args
[n_changes
+ 2];
5554 r
= acquire_bus(BUS_MANAGER
, &bus
);
5558 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5559 for (i
= 0; i
< n_changes
; i
++)
5560 new_args
[i
+ 1] = basename(changes
[i
].path
);
5561 new_args
[i
+ 1] = NULL
;
5563 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5567 unit_file_changes_free(changes
, n_changes
);
5572 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5573 _cleanup_strv_free_
char **names
= NULL
;
5574 _cleanup_free_
char *target
= NULL
;
5575 const char *verb
= argv
[0];
5582 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5584 return log_error_errno(r
, "Failed to mangle unit name: %m");
5586 r
= mangle_names(strv_skip(argv
, 2), &names
);
5590 if (streq(verb
, "add-wants"))
5592 else if (streq(verb
, "add-requires"))
5593 dep
= UNIT_REQUIRES
;
5595 assert_not_reached("Unknown verb");
5597 if (install_client_side()) {
5598 UnitFileChange
*changes
= NULL
;
5599 unsigned n_changes
= 0;
5601 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5602 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
5603 unit_file_changes_free(changes
, n_changes
);
5606 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5607 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5610 polkit_agent_open_if_enabled();
5612 r
= acquire_bus(BUS_MANAGER
, &bus
);
5616 r
= sd_bus_message_new_method_call(
5619 "org.freedesktop.systemd1",
5620 "/org/freedesktop/systemd1",
5621 "org.freedesktop.systemd1.Manager",
5622 "AddDependencyUnitFiles");
5624 return bus_log_create_error(r
);
5626 r
= sd_bus_message_append_strv(m
, names
);
5628 return bus_log_create_error(r
);
5630 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5632 return bus_log_create_error(r
);
5634 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5636 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
5638 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5644 return daemon_reload(argc
, argv
, userdata
);
5648 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5651 if (install_client_side()) {
5652 UnitFileChange
*changes
= NULL
;
5653 unsigned n_changes
= 0;
5655 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5656 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
5657 unit_file_changes_free(changes
, n_changes
);
5660 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5661 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5664 polkit_agent_open_if_enabled();
5666 r
= acquire_bus(BUS_MANAGER
, &bus
);
5670 r
= sd_bus_call_method(
5672 "org.freedesktop.systemd1",
5673 "/org/freedesktop/systemd1",
5674 "org.freedesktop.systemd1.Manager",
5675 "PresetAllUnitFiles",
5679 unit_file_preset_mode_to_string(arg_preset_mode
),
5683 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
5685 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5691 return daemon_reload(argc
, argv
, userdata
);
5695 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5697 _cleanup_strv_free_
char **names
= NULL
;
5702 r
= mangle_names(strv_skip(argv
, 1), &names
);
5706 r
= enable_sysv_units(argv
[0], names
);
5712 if (install_client_side()) {
5714 STRV_FOREACH(name
, names
) {
5715 UnitFileState state
;
5717 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5719 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5723 UNIT_FILE_ENABLED_RUNTIME
,
5726 UNIT_FILE_GENERATED
))
5730 puts(unit_file_state_to_string(state
));
5734 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5737 r
= acquire_bus(BUS_MANAGER
, &bus
);
5741 STRV_FOREACH(name
, names
) {
5742 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5745 r
= sd_bus_call_method(
5747 "org.freedesktop.systemd1",
5748 "/org/freedesktop/systemd1",
5749 "org.freedesktop.systemd1.Manager",
5755 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5757 r
= sd_bus_message_read(reply
, "s", &s
);
5759 return bus_log_parse_error(r
);
5761 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
5769 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
5772 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5773 _cleanup_free_
char *state
= NULL
;
5777 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5780 return EXIT_FAILURE
;
5783 r
= acquire_bus(BUS_MANAGER
, &bus
);
5787 r
= sd_bus_get_property_string(
5789 "org.freedesktop.systemd1",
5790 "/org/freedesktop/systemd1",
5791 "org.freedesktop.systemd1.Manager",
5804 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5807 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5808 _cleanup_free_
char *t
= NULL
;
5812 assert(original_path
);
5815 r
= tempfn_random(new_path
, NULL
, &t
);
5817 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5819 r
= mkdir_parents(new_path
, 0755);
5821 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5823 r
= copy_file(original_path
, t
, 0, 0644, 0);
5828 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5831 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5839 static int get_file_to_edit(
5840 const LookupPaths
*paths
,
5844 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
5849 path
= strjoin(paths
->persistent_config
, "/", name
, NULL
);
5854 run
= strjoin(paths
->runtime_config
, name
, NULL
);
5860 if (access(path
, F_OK
) >= 0) {
5861 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5875 static int unit_file_create_dropin(
5876 const LookupPaths
*paths
,
5877 const char *unit_name
,
5878 char **ret_new_path
,
5879 char **ret_tmp_path
) {
5881 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5885 assert(ret_new_path
);
5886 assert(ret_tmp_path
);
5888 ending
= strjoina(unit_name
, ".d/override.conf");
5889 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
5893 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5899 *ret_new_path
= tmp_new_path
;
5900 *ret_tmp_path
= tmp_tmp_path
;
5905 static int unit_file_create_copy(
5906 const LookupPaths
*paths
,
5907 const char *unit_name
,
5908 const char *fragment_path
,
5909 char **ret_new_path
,
5910 char **ret_tmp_path
) {
5912 char *tmp_new_path
, *tmp_tmp_path
;
5915 assert(fragment_path
);
5917 assert(ret_new_path
);
5918 assert(ret_tmp_path
);
5920 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
5924 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5927 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5932 if (response
!= 'y') {
5933 log_warning("%s ignored", unit_name
);
5939 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5941 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5946 *ret_new_path
= tmp_new_path
;
5947 *ret_tmp_path
= tmp_tmp_path
;
5952 static int run_editor(char **paths
) {
5960 return log_error_errno(errno
, "Failed to fork: %m");
5964 char *editor
, **editor_args
= NULL
;
5965 char **tmp_path
, **original_path
, *p
;
5966 unsigned n_editor_args
= 0, i
= 1;
5969 (void) reset_all_signal_handlers();
5970 (void) reset_signal_mask();
5972 argc
= strv_length(paths
)/2 + 1;
5974 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5975 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5976 * we try to execute well known editors
5978 editor
= getenv("SYSTEMD_EDITOR");
5980 editor
= getenv("EDITOR");
5982 editor
= getenv("VISUAL");
5984 if (!isempty(editor
)) {
5985 editor_args
= strv_split(editor
, WHITESPACE
);
5988 _exit(EXIT_FAILURE
);
5990 n_editor_args
= strv_length(editor_args
);
5991 argc
+= n_editor_args
- 1;
5993 args
= newa(const char*, argc
+ 1);
5995 if (n_editor_args
> 0) {
5996 args
[0] = editor_args
[0];
5997 for (; i
< n_editor_args
; i
++)
5998 args
[i
] = editor_args
[i
];
6001 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6002 args
[i
] = *tmp_path
;
6007 if (n_editor_args
> 0)
6008 execvp(args
[0], (char* const*) args
);
6010 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6012 execvp(p
, (char* const*) args
);
6013 /* We do not fail if the editor doesn't exist
6014 * because we want to try each one of them before
6017 if (errno
!= ENOENT
) {
6018 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6019 _exit(EXIT_FAILURE
);
6023 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6024 _exit(EXIT_FAILURE
);
6027 r
= wait_for_terminate_and_warn("editor", pid
, true);
6029 return log_error_errno(r
, "Failed to wait for child: %m");
6034 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6035 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6042 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6046 STRV_FOREACH(name
, names
) {
6047 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
;
6049 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6055 // FIXME: support units with path==NULL (no FragmentPath)
6056 log_error("No fragment exists for %s.", *name
);
6061 r
= unit_file_create_copy(&lp
, *name
, path
, &new_path
, &tmp_path
);
6063 r
= unit_file_create_dropin(&lp
, *name
, &new_path
, &tmp_path
);
6067 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6070 new_path
= tmp_path
= NULL
;
6076 static int edit(int argc
, char *argv
[], void *userdata
) {
6077 _cleanup_strv_free_
char **names
= NULL
;
6078 _cleanup_strv_free_
char **paths
= NULL
;
6079 char **original
, **tmp
;
6084 log_error("Cannot edit units if not on a tty.");
6088 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6089 log_error("Cannot edit units remotely.");
6093 r
= acquire_bus(BUS_MANAGER
, &bus
);
6097 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6099 return log_error_errno(r
, "Failed to expand names: %m");
6101 r
= find_paths_to_edit(bus
, names
, &paths
);
6105 if (strv_isempty(paths
))
6108 r
= run_editor(paths
);
6112 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6113 /* If the temporary file is empty we ignore it. It's
6114 * useful if the user wants to cancel its modification
6116 if (null_or_empty_path(*tmp
)) {
6117 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6121 r
= rename(*tmp
, *original
);
6123 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6130 if (!arg_no_reload
&& !install_client_side())
6131 r
= daemon_reload(argc
, argv
, userdata
);
6134 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6135 (void) unlink(*tmp
);
6137 /* Removing empty dropin dirs */
6139 _cleanup_free_
char *dir
;
6141 dir
= dirname_malloc(*original
);
6145 /* no need to check if the dir is empty, rmdir
6146 * does nothing if it is not the case.
6155 static void systemctl_help(void) {
6157 pager_open(arg_no_pager
, false);
6159 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6160 "Query or send control commands to the systemd manager.\n\n"
6161 " -h --help Show this help\n"
6162 " --version Show package version\n"
6163 " --system Connect to system manager\n"
6164 " --user Connect to user service manager\n"
6165 " -H --host=[USER@]HOST\n"
6166 " Operate on remote host\n"
6167 " -M --machine=CONTAINER\n"
6168 " Operate on local container\n"
6169 " -t --type=TYPE List units of a particular type\n"
6170 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6171 " -p --property=NAME Show only properties by this name\n"
6172 " -a --all Show all loaded units/properties, including dead/empty\n"
6173 " ones. To list all units installed on the system, use\n"
6174 " the 'list-unit-files' command instead.\n"
6175 " -l --full Don't ellipsize unit names on output\n"
6176 " -r --recursive Show unit list of host and local containers\n"
6177 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6178 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6179 " queueing a new job\n"
6180 " --show-types When showing sockets, explicitly show their type\n"
6181 " --value When showing properties, only print the value\n"
6182 " -i --ignore-inhibitors\n"
6183 " When shutting down or sleeping, ignore inhibitors\n"
6184 " --kill-who=WHO Who to send signal to\n"
6185 " -s --signal=SIGNAL Which signal to send\n"
6186 " --now Start or stop unit in addition to enabling or disabling it\n"
6187 " -q --quiet Suppress output\n"
6188 " --no-block Do not wait until operation finished\n"
6189 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6190 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6191 " --no-legend Do not print a legend (column headers and hints)\n"
6192 " --no-pager Do not pipe output into a pager\n"
6193 " --no-ask-password\n"
6194 " Do not ask for system passwords\n"
6195 " --global Enable/disable unit files globally\n"
6196 " --runtime Enable unit files only temporarily until next reboot\n"
6197 " -f --force When enabling unit files, override existing symlinks\n"
6198 " When shutting down, execute action immediately\n"
6199 " --preset-mode= Apply only enable, only disable, or all presets\n"
6200 " --root=PATH Enable unit files in the specified root directory\n"
6201 " -n --lines=INTEGER Number of journal entries to show\n"
6202 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6203 " short-precise, short-monotonic, verbose,\n"
6204 " export, json, json-pretty, json-sse, cat)\n"
6205 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6206 " --plain Print unit dependencies as a list instead of a tree\n\n"
6208 " list-units [PATTERN...] List loaded units\n"
6209 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6210 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6211 " start NAME... Start (activate) one or more units\n"
6212 " stop NAME... Stop (deactivate) one or more units\n"
6213 " reload NAME... Reload one or more units\n"
6214 " restart NAME... Start or restart one or more units\n"
6215 " try-restart NAME... Restart one or more units if active\n"
6216 " reload-or-restart NAME... Reload one or more units if possible,\n"
6217 " otherwise start or restart\n"
6218 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6219 " if supported, otherwise restart\n"
6220 " isolate NAME Start one unit and stop all others\n"
6221 " kill NAME... Send signal to processes of a unit\n"
6222 " is-active PATTERN... Check whether units are active\n"
6223 " is-failed PATTERN... Check whether units are failed\n"
6224 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6225 " show [PATTERN...|JOB...] Show properties of one or more\n"
6226 " units/jobs or the manager\n"
6227 " cat PATTERN... Show files and drop-ins of one or more units\n"
6228 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6229 " help PATTERN...|PID... Show manual for one or more units\n"
6230 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6232 " list-dependencies [NAME] Recursively show units which are required\n"
6233 " or wanted by this unit or by which this\n"
6234 " unit is required or wanted\n\n"
6235 "Unit File Commands:\n"
6236 " list-unit-files [PATTERN...] List installed unit files\n"
6237 " enable NAME... Enable one or more unit files\n"
6238 " disable NAME... Disable one or more unit files\n"
6239 " reenable NAME... Reenable one or more unit files\n"
6240 " preset NAME... Enable/disable one or more unit files\n"
6241 " based on preset configuration\n"
6242 " preset-all Enable/disable all unit files based on\n"
6243 " preset configuration\n"
6244 " is-enabled NAME... Check whether unit files are enabled\n"
6245 " mask NAME... Mask one or more units\n"
6246 " unmask NAME... Unmask one or more units\n"
6247 " link PATH... Link one or more units files into\n"
6248 " the search path\n"
6249 " revert NAME... Revert one or more unit files to vendor\n"
6251 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6252 " on specified one or more units\n"
6253 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6254 " on specified one or more units\n"
6255 " edit NAME... Edit one or more unit files\n"
6256 " get-default Get the name of the default target\n"
6257 " set-default NAME Set the default target\n\n"
6258 "Machine Commands:\n"
6259 " list-machines [PATTERN...] List local containers and host\n\n"
6261 " list-jobs [PATTERN...] List jobs\n"
6262 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6263 "Environment Commands:\n"
6264 " show-environment Dump environment\n"
6265 " set-environment NAME=VALUE... Set one or more environment variables\n"
6266 " unset-environment NAME... Unset one or more environment variables\n"
6267 " import-environment [NAME...] Import all or some environment variables\n\n"
6268 "Manager Lifecycle Commands:\n"
6269 " daemon-reload Reload systemd manager configuration\n"
6270 " daemon-reexec Reexecute systemd manager\n\n"
6271 "System Commands:\n"
6272 " is-system-running Check whether system is fully running\n"
6273 " default Enter system default mode\n"
6274 " rescue Enter system rescue mode\n"
6275 " emergency Enter system emergency mode\n"
6276 " halt Shut down and halt the system\n"
6277 " poweroff Shut down and power-off the system\n"
6278 " reboot [ARG] Shut down and reboot the system\n"
6279 " kexec Shut down and reboot the system with kexec\n"
6280 " exit [EXIT_CODE] Request user instance or container exit\n"
6281 " switch-root ROOT [INIT] Change to a different root file system\n"
6282 " suspend Suspend the system\n"
6283 " hibernate Hibernate the system\n"
6284 " hybrid-sleep Hibernate and suspend the system\n",
6285 program_invocation_short_name
);
6288 static void halt_help(void) {
6289 printf("%s [OPTIONS...]%s\n\n"
6290 "%s the system.\n\n"
6291 " --help Show this help\n"
6292 " --halt Halt the machine\n"
6293 " -p --poweroff Switch off the machine\n"
6294 " --reboot Reboot the machine\n"
6295 " -f --force Force immediate halt/power-off/reboot\n"
6296 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6297 " -d --no-wtmp Don't write wtmp record\n"
6298 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6299 program_invocation_short_name
,
6300 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6301 arg_action
== ACTION_REBOOT
? "Reboot" :
6302 arg_action
== ACTION_POWEROFF
? "Power off" :
6306 static void shutdown_help(void) {
6307 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6308 "Shut down the system.\n\n"
6309 " --help Show this help\n"
6310 " -H --halt Halt the machine\n"
6311 " -P --poweroff Power-off the machine\n"
6312 " -r --reboot Reboot the machine\n"
6313 " -h Equivalent to --poweroff, overridden by --halt\n"
6314 " -k Don't halt/power-off/reboot, just send warnings\n"
6315 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6316 " -c Cancel a pending shutdown\n",
6317 program_invocation_short_name
);
6320 static void telinit_help(void) {
6321 printf("%s [OPTIONS...] {COMMAND}\n\n"
6322 "Send control commands to the init daemon.\n\n"
6323 " --help Show this help\n"
6324 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6326 " 0 Power-off the machine\n"
6327 " 6 Reboot the machine\n"
6328 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6329 " 1, s, S Enter rescue mode\n"
6330 " q, Q Reload init daemon configuration\n"
6331 " u, U Reexecute init daemon\n",
6332 program_invocation_short_name
);
6335 static void runlevel_help(void) {
6336 printf("%s [OPTIONS...]\n\n"
6337 "Prints the previous and current runlevel of the init system.\n\n"
6338 " --help Show this help\n",
6339 program_invocation_short_name
);
6342 static void help_types(void) {
6346 puts("Available unit types:");
6347 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6348 puts(unit_type_to_string(i
));
6351 static void help_states(void) {
6355 puts("Available unit load states:");
6356 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6357 puts(unit_load_state_to_string(i
));
6360 puts("\nAvailable unit active states:");
6361 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6362 puts(unit_active_state_to_string(i
));
6365 puts("\nAvailable automount unit substates:");
6366 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6367 puts(automount_state_to_string(i
));
6370 puts("\nAvailable busname unit substates:");
6371 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6372 puts(busname_state_to_string(i
));
6375 puts("\nAvailable device unit substates:");
6376 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6377 puts(device_state_to_string(i
));
6380 puts("\nAvailable mount unit substates:");
6381 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6382 puts(mount_state_to_string(i
));
6385 puts("\nAvailable path unit substates:");
6386 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6387 puts(path_state_to_string(i
));
6390 puts("\nAvailable scope unit substates:");
6391 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6392 puts(scope_state_to_string(i
));
6395 puts("\nAvailable service unit substates:");
6396 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6397 puts(service_state_to_string(i
));
6400 puts("\nAvailable slice unit substates:");
6401 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6402 puts(slice_state_to_string(i
));
6405 puts("\nAvailable socket unit substates:");
6406 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6407 puts(socket_state_to_string(i
));
6410 puts("\nAvailable swap unit substates:");
6411 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6412 puts(swap_state_to_string(i
));
6415 puts("\nAvailable target unit substates:");
6416 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6417 puts(target_state_to_string(i
));
6420 puts("\nAvailable timer unit substates:");
6421 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6422 puts(timer_state_to_string(i
));
6425 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6434 ARG_IGNORE_DEPENDENCIES
,
6447 ARG_NO_ASK_PASSWORD
,
6460 static const struct option options
[] = {
6461 { "help", no_argument
, NULL
, 'h' },
6462 { "version", no_argument
, NULL
, ARG_VERSION
},
6463 { "type", required_argument
, NULL
, 't' },
6464 { "property", required_argument
, NULL
, 'p' },
6465 { "all", no_argument
, NULL
, 'a' },
6466 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6467 { "after", no_argument
, NULL
, ARG_AFTER
},
6468 { "before", no_argument
, NULL
, ARG_BEFORE
},
6469 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6470 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6471 { "full", no_argument
, NULL
, 'l' },
6472 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6473 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6474 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6475 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6476 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6477 { "value", no_argument
, NULL
, ARG_VALUE
},
6478 { "user", no_argument
, NULL
, ARG_USER
},
6479 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6480 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6481 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6482 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6483 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6484 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6485 { "quiet", no_argument
, NULL
, 'q' },
6486 { "root", required_argument
, NULL
, ARG_ROOT
},
6487 { "force", no_argument
, NULL
, ARG_FORCE
},
6488 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6489 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6490 { "signal", required_argument
, NULL
, 's' },
6491 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6492 { "host", required_argument
, NULL
, 'H' },
6493 { "machine", required_argument
, NULL
, 'M' },
6494 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6495 { "lines", required_argument
, NULL
, 'n' },
6496 { "output", required_argument
, NULL
, 'o' },
6497 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6498 { "state", required_argument
, NULL
, ARG_STATE
},
6499 { "recursive", no_argument
, NULL
, 'r' },
6500 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6501 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6502 { "now", no_argument
, NULL
, ARG_NOW
},
6503 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6513 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6514 arg_ask_password
= true;
6516 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6528 if (isempty(optarg
)) {
6529 log_error("--type requires arguments.");
6535 _cleanup_free_
char *type
= NULL
;
6537 r
= extract_first_word(&p
, &type
, ",", 0);
6539 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6544 if (streq(type
, "help")) {
6549 if (unit_type_from_string(type
) >= 0) {
6550 if (strv_push(&arg_types
, type
) < 0)
6556 /* It's much nicer to use --state= for
6557 * load states, but let's support this
6558 * in --types= too for compatibility
6559 * with old versions */
6560 if (unit_load_state_from_string(type
) >= 0) {
6561 if (strv_push(&arg_states
, type
) < 0)
6567 log_error("Unknown unit type or load state '%s'.", type
);
6568 log_info("Use -t help to see a list of allowed values.");
6576 /* Make sure that if the empty property list
6577 was specified, we won't show any properties. */
6578 if (isempty(optarg
) && !arg_properties
) {
6579 arg_properties
= new0(char*, 1);
6580 if (!arg_properties
)
6585 _cleanup_free_
char *prop
= NULL
;
6587 r
= extract_first_word(&p
, &prop
, ",", 0);
6589 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6594 if (strv_push(&arg_properties
, prop
) < 0)
6601 /* If the user asked for a particular
6602 * property, show it to him, even if it is
6614 arg_dependency
= DEPENDENCY_REVERSE
;
6618 arg_dependency
= DEPENDENCY_AFTER
;
6622 arg_dependency
= DEPENDENCY_BEFORE
;
6625 case ARG_SHOW_TYPES
:
6626 arg_show_types
= true;
6634 arg_job_mode
= optarg
;
6638 arg_job_mode
= "fail";
6641 case ARG_IRREVERSIBLE
:
6642 arg_job_mode
= "replace-irreversibly";
6645 case ARG_IGNORE_DEPENDENCIES
:
6646 arg_job_mode
= "ignore-dependencies";
6650 arg_scope
= UNIT_FILE_USER
;
6654 arg_scope
= UNIT_FILE_SYSTEM
;
6658 arg_scope
= UNIT_FILE_GLOBAL
;
6662 arg_no_block
= true;
6666 arg_no_legend
= true;
6670 arg_no_pager
= true;
6678 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
6688 if (strv_extend(&arg_states
, "failed") < 0)
6706 arg_no_reload
= true;
6710 arg_kill_who
= optarg
;
6714 arg_signal
= signal_from_string_try_harder(optarg
);
6715 if (arg_signal
< 0) {
6716 log_error("Failed to parse signal string %s.", optarg
);
6721 case ARG_NO_ASK_PASSWORD
:
6722 arg_ask_password
= false;
6726 arg_transport
= BUS_TRANSPORT_REMOTE
;
6731 arg_transport
= BUS_TRANSPORT_MACHINE
;
6740 if (safe_atou(optarg
, &arg_lines
) < 0) {
6741 log_error("Failed to parse lines '%s'", optarg
);
6747 arg_output
= output_mode_from_string(optarg
);
6748 if (arg_output
< 0) {
6749 log_error("Unknown output '%s'.", optarg
);
6755 arg_ignore_inhibitors
= true;
6762 case ARG_FIRMWARE_SETUP
:
6763 arg_firmware_setup
= true;
6767 if (isempty(optarg
)) {
6768 log_error("--signal requires arguments.");
6774 _cleanup_free_
char *s
= NULL
;
6776 r
= extract_first_word(&p
, &s
, ",", 0);
6778 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6783 if (streq(s
, "help")) {
6788 if (strv_push(&arg_states
, s
) < 0)
6797 if (geteuid() != 0) {
6798 log_error("--recursive requires root privileges.");
6802 arg_recursive
= true;
6805 case ARG_PRESET_MODE
:
6807 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6808 if (arg_preset_mode
< 0) {
6809 log_error("Failed to parse preset mode: %s.", optarg
);
6820 if (strv_extend(&arg_wall
, optarg
) < 0)
6828 assert_not_reached("Unhandled option");
6831 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6832 log_error("Cannot access user instance remotely.");
6839 static int halt_parse_argv(int argc
, char *argv
[]) {
6848 static const struct option options
[] = {
6849 { "help", no_argument
, NULL
, ARG_HELP
},
6850 { "halt", no_argument
, NULL
, ARG_HALT
},
6851 { "poweroff", no_argument
, NULL
, 'p' },
6852 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6853 { "force", no_argument
, NULL
, 'f' },
6854 { "wtmp-only", no_argument
, NULL
, 'w' },
6855 { "no-wtmp", no_argument
, NULL
, 'd' },
6856 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6865 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6866 if (runlevel
== '0' || runlevel
== '6')
6869 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6877 arg_action
= ACTION_HALT
;
6881 if (arg_action
!= ACTION_REBOOT
)
6882 arg_action
= ACTION_POWEROFF
;
6886 arg_action
= ACTION_REBOOT
;
6908 /* Compatibility nops */
6915 assert_not_reached("Unhandled option");
6918 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6919 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6922 } else if (optind
< argc
) {
6923 log_error("Too many arguments.");
6930 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
6934 if (streq(t
, "now"))
6936 else if (!strchr(t
, ':')) {
6939 if (safe_atou64(t
, &u
) < 0)
6942 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6951 hour
= strtol(t
, &e
, 10);
6952 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6955 minute
= strtol(e
+1, &e
, 10);
6956 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6959 n
= now(CLOCK_REALTIME
);
6960 s
= (time_t) (n
/ USEC_PER_SEC
);
6962 assert_se(localtime_r(&s
, &tm
));
6964 tm
.tm_hour
= (int) hour
;
6965 tm
.tm_min
= (int) minute
;
6968 assert_se(s
= mktime(&tm
));
6970 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6973 *_u
+= USEC_PER_DAY
;
6979 static int shutdown_parse_argv(int argc
, char *argv
[]) {
6986 static const struct option options
[] = {
6987 { "help", no_argument
, NULL
, ARG_HELP
},
6988 { "halt", no_argument
, NULL
, 'H' },
6989 { "poweroff", no_argument
, NULL
, 'P' },
6990 { "reboot", no_argument
, NULL
, 'r' },
6991 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
6992 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7002 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7010 arg_action
= ACTION_HALT
;
7014 arg_action
= ACTION_POWEROFF
;
7019 arg_action
= ACTION_KEXEC
;
7021 arg_action
= ACTION_REBOOT
;
7025 arg_action
= ACTION_KEXEC
;
7029 if (arg_action
!= ACTION_HALT
)
7030 arg_action
= ACTION_POWEROFF
;
7045 /* Compatibility nops */
7049 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7056 assert_not_reached("Unhandled option");
7059 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7060 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7062 log_error("Failed to parse time specification: %s", argv
[optind
]);
7066 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7068 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7069 /* No time argument for shutdown cancel */
7070 wall
= argv
+ optind
;
7071 else if (argc
> optind
+ 1)
7072 /* We skip the time argument */
7073 wall
= argv
+ optind
+ 1;
7076 arg_wall
= strv_copy(wall
);
7086 static int telinit_parse_argv(int argc
, char *argv
[]) {
7093 static const struct option options
[] = {
7094 { "help", no_argument
, NULL
, ARG_HELP
},
7095 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7099 static const struct {
7103 { '0', ACTION_POWEROFF
},
7104 { '6', ACTION_REBOOT
},
7105 { '1', ACTION_RESCUE
},
7106 { '2', ACTION_RUNLEVEL2
},
7107 { '3', ACTION_RUNLEVEL3
},
7108 { '4', ACTION_RUNLEVEL4
},
7109 { '5', ACTION_RUNLEVEL5
},
7110 { 's', ACTION_RESCUE
},
7111 { 'S', ACTION_RESCUE
},
7112 { 'q', ACTION_RELOAD
},
7113 { 'Q', ACTION_RELOAD
},
7114 { 'u', ACTION_REEXEC
},
7115 { 'U', ACTION_REEXEC
}
7124 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7139 assert_not_reached("Unhandled option");
7142 if (optind
>= argc
) {
7143 log_error("%s: required argument missing.", program_invocation_short_name
);
7147 if (optind
+ 1 < argc
) {
7148 log_error("Too many arguments.");
7152 if (strlen(argv
[optind
]) != 1) {
7153 log_error("Expected single character argument.");
7157 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7158 if (table
[i
].from
== argv
[optind
][0])
7161 if (i
>= ELEMENTSOF(table
)) {
7162 log_error("Unknown command '%s'.", argv
[optind
]);
7166 arg_action
= table
[i
].to
;
7173 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7179 static const struct option options
[] = {
7180 { "help", no_argument
, NULL
, ARG_HELP
},
7189 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7200 assert_not_reached("Unhandled option");
7203 if (optind
< argc
) {
7204 log_error("Too many arguments.");
7211 static int parse_argv(int argc
, char *argv
[]) {
7215 if (program_invocation_short_name
) {
7217 if (strstr(program_invocation_short_name
, "halt")) {
7218 arg_action
= ACTION_HALT
;
7219 return halt_parse_argv(argc
, argv
);
7220 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7221 arg_action
= ACTION_POWEROFF
;
7222 return halt_parse_argv(argc
, argv
);
7223 } else if (strstr(program_invocation_short_name
, "reboot")) {
7225 arg_action
= ACTION_KEXEC
;
7227 arg_action
= ACTION_REBOOT
;
7228 return halt_parse_argv(argc
, argv
);
7229 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7230 arg_action
= ACTION_POWEROFF
;
7231 return shutdown_parse_argv(argc
, argv
);
7232 } else if (strstr(program_invocation_short_name
, "init")) {
7234 if (sd_booted() > 0) {
7235 arg_action
= _ACTION_INVALID
;
7236 return telinit_parse_argv(argc
, argv
);
7238 /* Hmm, so some other init system is
7239 * running, we need to forward this
7240 * request to it. For now we simply
7241 * guess that it is Upstart. */
7243 execv(TELINIT
, argv
);
7245 log_error("Couldn't find an alternative telinit implementation to spawn.");
7249 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7250 arg_action
= ACTION_RUNLEVEL
;
7251 return runlevel_parse_argv(argc
, argv
);
7255 arg_action
= ACTION_SYSTEMCTL
;
7256 return systemctl_parse_argv(argc
, argv
);
7259 #ifdef HAVE_SYSV_COMPAT
7260 _pure_
static int action_to_runlevel(void) {
7262 static const char table
[_ACTION_MAX
] = {
7263 [ACTION_HALT
] = '0',
7264 [ACTION_POWEROFF
] = '0',
7265 [ACTION_REBOOT
] = '6',
7266 [ACTION_RUNLEVEL2
] = '2',
7267 [ACTION_RUNLEVEL3
] = '3',
7268 [ACTION_RUNLEVEL4
] = '4',
7269 [ACTION_RUNLEVEL5
] = '5',
7270 [ACTION_RESCUE
] = '1'
7273 assert(arg_action
< _ACTION_MAX
);
7275 return table
[arg_action
];
7279 static int talk_initctl(void) {
7280 #ifdef HAVE_SYSV_COMPAT
7281 struct init_request request
= {
7282 .magic
= INIT_MAGIC
,
7284 .cmd
= INIT_CMD_RUNLVL
7287 _cleanup_close_
int fd
= -1;
7291 rl
= action_to_runlevel();
7295 request
.runlevel
= rl
;
7297 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7299 if (errno
== ENOENT
)
7302 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7305 r
= loop_write(fd
, &request
, sizeof(request
), false);
7307 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7315 static int systemctl_main(int argc
, char *argv
[]) {
7317 static const Verb verbs
[] = {
7318 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7319 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7320 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7321 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7322 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7323 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7324 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7325 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7326 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7327 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7328 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7329 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7330 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7331 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7332 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7333 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7334 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7335 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7336 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7337 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7338 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7339 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7340 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7341 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7342 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7343 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7344 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7345 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7346 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7347 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7348 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7349 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7350 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7351 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7352 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7353 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7354 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7355 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7356 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7357 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7358 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7359 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7360 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7361 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7362 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7363 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7364 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7365 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7366 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7367 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7368 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7369 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7370 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7371 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7372 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7373 { "link", 2, VERB_ANY
, 0, enable_unit
},
7374 { "revert", 2, VERB_ANY
, 0, enable_unit
},
7375 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7376 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7377 { "set-default", 2, 2, 0, set_default
},
7378 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7379 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7380 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7381 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7382 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7383 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7387 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7390 static int reload_with_fallback(void) {
7392 /* First, try systemd via D-Bus. */
7393 if (daemon_reload(0, NULL
, NULL
) >= 0)
7396 /* Nothing else worked, so let's try signals */
7397 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7399 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7400 return log_error_errno(errno
, "kill() failed: %m");
7405 static int start_with_fallback(void) {
7407 /* First, try systemd via D-Bus. */
7408 if (start_unit(0, NULL
, NULL
) >= 0)
7411 /* Nothing else worked, so let's try
7413 if (talk_initctl() > 0)
7416 log_error("Failed to talk to init daemon.");
7420 static int halt_now(enum action a
) {
7423 /* The kernel will automaticall flush ATA disks and suchlike
7424 * on reboot(), but the file systems need to be synce'd
7425 * explicitly in advance. */
7428 /* Make sure C-A-D is handled by the kernel from this point
7430 (void) reboot(RB_ENABLE_CAD
);
7435 log_info("Halting.");
7436 (void) reboot(RB_HALT_SYSTEM
);
7439 case ACTION_POWEROFF
:
7440 log_info("Powering off.");
7441 (void) reboot(RB_POWER_OFF
);
7445 case ACTION_REBOOT
: {
7446 _cleanup_free_
char *param
= NULL
;
7448 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
7450 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
7452 if (!isempty(param
)) {
7453 log_info("Rebooting with argument '%s'.", param
);
7454 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7455 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
7458 log_info("Rebooting.");
7459 (void) reboot(RB_AUTOBOOT
);
7464 assert_not_reached("Unknown action.");
7468 static int logind_schedule_shutdown(void) {
7471 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7472 char date
[FORMAT_TIMESTAMP_MAX
];
7477 (void) logind_set_wall_message();
7479 r
= acquire_bus(BUS_FULL
, &bus
);
7483 switch (arg_action
) {
7487 case ACTION_POWEROFF
:
7488 action
= "poweroff";
7503 action
= strjoina("dry-", action
);
7505 r
= sd_bus_call_method(
7507 "org.freedesktop.login1",
7508 "/org/freedesktop/login1",
7509 "org.freedesktop.login1.Manager",
7517 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7519 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7522 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7527 static int halt_main(void) {
7530 r
= logind_check_inhibitors(arg_action
);
7535 return logind_schedule_shutdown();
7537 if (geteuid() != 0) {
7538 if (arg_dry
|| arg_force
> 0) {
7539 log_error("Must be root.");
7543 /* Try logind if we are a normal user and no special
7544 * mode applies. Maybe PolicyKit allows us to shutdown
7546 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7547 r
= logind_reboot(arg_action
);
7550 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7551 /* requested operation is not
7552 * supported on the local system or
7553 * already in progress */
7555 /* on all other errors, try low-level operation */
7559 if (!arg_dry
&& !arg_force
)
7560 return start_with_fallback();
7562 assert(geteuid() == 0);
7565 if (sd_booted() > 0)
7566 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7568 r
= utmp_put_shutdown();
7570 log_warning_errno(r
, "Failed to write utmp record: %m");
7577 r
= halt_now(arg_action
);
7578 return log_error_errno(r
, "Failed to reboot: %m");
7581 static int runlevel_main(void) {
7582 int r
, runlevel
, previous
;
7584 r
= utmp_get_runlevel(&runlevel
, &previous
);
7591 previous
<= 0 ? 'N' : previous
,
7592 runlevel
<= 0 ? 'N' : runlevel
);
7597 static int logind_cancel_shutdown(void) {
7599 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7603 r
= acquire_bus(BUS_FULL
, &bus
);
7607 (void) logind_set_wall_message();
7609 r
= sd_bus_call_method(
7611 "org.freedesktop.login1",
7612 "/org/freedesktop/login1",
7613 "org.freedesktop.login1.Manager",
7614 "CancelScheduledShutdown",
7618 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7622 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7627 int main(int argc
, char*argv
[]) {
7630 setlocale(LC_ALL
, "");
7631 log_parse_environment();
7634 /* Explicitly not on_tty() to avoid setting cached value.
7635 * This becomes relevant for piping output which might be
7637 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7639 r
= parse_argv(argc
, argv
);
7643 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7644 log_info("Running in chroot, ignoring request.");
7649 /* systemctl_main() will print an error message for the bus
7650 * connection, but only if it needs to */
7652 switch (arg_action
) {
7654 case ACTION_SYSTEMCTL
:
7655 r
= systemctl_main(argc
, argv
);
7659 case ACTION_POWEROFF
:
7665 case ACTION_RUNLEVEL2
:
7666 case ACTION_RUNLEVEL3
:
7667 case ACTION_RUNLEVEL4
:
7668 case ACTION_RUNLEVEL5
:
7670 case ACTION_EMERGENCY
:
7671 case ACTION_DEFAULT
:
7672 r
= start_with_fallback();
7677 r
= reload_with_fallback();
7680 case ACTION_CANCEL_SHUTDOWN
:
7681 r
= logind_cancel_shutdown();
7684 case ACTION_RUNLEVEL
:
7685 r
= runlevel_main();
7688 case _ACTION_INVALID
:
7690 assert_not_reached("Unknown action");
7695 ask_password_agent_close();
7696 polkit_agent_close();
7698 strv_free(arg_types
);
7699 strv_free(arg_states
);
7700 strv_free(arg_properties
);
7702 strv_free(arg_wall
);
7707 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7709 return r
< 0 ? EXIT_FAILURE
: r
;