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_show_types
= false;
107 static bool arg_ignore_inhibitors
= false;
108 static bool arg_dry
= false;
109 static bool arg_quiet
= false;
110 static bool arg_full
= false;
111 static bool arg_recursive
= false;
112 static int arg_force
= 0;
113 static bool arg_ask_password
= false;
114 static bool arg_runtime
= false;
115 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
116 static char **arg_wall
= NULL
;
117 static const char *arg_kill_who
= NULL
;
118 static int arg_signal
= SIGTERM
;
119 static char *arg_root
= NULL
;
120 static usec_t arg_when
= 0;
142 ACTION_CANCEL_SHUTDOWN
,
144 } arg_action
= ACTION_SYSTEMCTL
;
145 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
146 static const char *arg_host
= NULL
;
147 static unsigned arg_lines
= 10;
148 static OutputMode arg_output
= OUTPUT_SHORT
;
149 static bool arg_plain
= false;
150 static bool arg_firmware_setup
= false;
151 static bool arg_now
= false;
153 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
154 static int halt_now(enum action a
);
155 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
157 static bool original_stdout_is_tty
;
159 typedef enum BusFocus
{
160 BUS_FULL
, /* The full bus indicated via --system or --user */
161 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
165 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
167 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
170 assert(focus
< _BUS_FOCUS_MAX
);
173 /* We only go directly to the manager, if we are using a local transport */
174 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
177 if (!busses
[focus
]) {
180 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
182 if (focus
== BUS_MANAGER
)
183 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
185 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
187 return log_error_errno(r
, "Failed to connect to bus: %m");
189 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
192 *ret
= busses
[focus
];
196 static void release_busses(void) {
199 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
200 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
203 static void ask_password_agent_open_if_enabled(void) {
205 /* Open the password agent as a child process if necessary */
207 if (!arg_ask_password
)
210 if (arg_scope
!= UNIT_FILE_SYSTEM
)
213 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
216 ask_password_agent_open();
219 static void polkit_agent_open_if_enabled(void) {
221 /* Open the polkit agent as a child process if necessary */
223 if (!arg_ask_password
)
226 if (arg_scope
!= UNIT_FILE_SYSTEM
)
229 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
235 static OutputFlags
get_output_flags(void) {
237 arg_all
* OUTPUT_SHOW_ALL
|
238 arg_full
* OUTPUT_FULL_WIDTH
|
239 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
240 colors_enabled() * OUTPUT_COLOR
|
241 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
244 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
247 if (!sd_bus_error_is_set(error
))
250 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
251 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
252 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
253 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
254 return EXIT_NOPERMISSION
;
256 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
257 return EXIT_NOTINSTALLED
;
259 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
260 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
261 return EXIT_NOTIMPLEMENTED
;
263 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
264 return EXIT_NOTCONFIGURED
;
272 static bool install_client_side(void) {
274 /* Decides when to execute enable/disable/... operations
275 * client-side rather than server-side. */
277 if (running_in_chroot() > 0)
280 if (sd_booted() <= 0)
283 if (!isempty(arg_root
))
286 if (arg_scope
== UNIT_FILE_GLOBAL
)
289 /* Unsupported environment variable, mostly for debugging purposes */
290 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
296 static int compare_unit_info(const void *a
, const void *b
) {
297 const UnitInfo
*u
= a
, *v
= b
;
301 /* First, order by machine */
302 if (!u
->machine
&& v
->machine
)
304 if (u
->machine
&& !v
->machine
)
306 if (u
->machine
&& v
->machine
) {
307 r
= strcasecmp(u
->machine
, v
->machine
);
312 /* Second, order by unit type */
313 d1
= strrchr(u
->id
, '.');
314 d2
= strrchr(v
->id
, '.');
316 r
= strcasecmp(d1
, d2
);
321 /* Third, order by name */
322 return strcasecmp(u
->id
, v
->id
);
325 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
326 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
332 dot
= strrchr(u
->id
, '.');
336 if (!strv_find(arg_types
, dot
+1))
346 if (streq(u
->active_state
, "inactive") || u
->following
[0])
352 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
353 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
355 unsigned n_shown
= 0;
358 max_id_len
= strlen("UNIT");
359 load_len
= strlen("LOAD");
360 active_len
= strlen("ACTIVE");
361 sub_len
= strlen("SUB");
362 job_len
= strlen("JOB");
365 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
366 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
367 load_len
= MAX(load_len
, strlen(u
->load_state
));
368 active_len
= MAX(active_len
, strlen(u
->active_state
));
369 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
371 if (u
->job_id
!= 0) {
372 job_len
= MAX(job_len
, strlen(u
->job_type
));
376 if (!arg_no_legend
&&
377 (streq(u
->active_state
, "failed") ||
378 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
382 if (!arg_full
&& original_stdout_is_tty
) {
385 id_len
= MIN(max_id_len
, 25u);
386 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
389 basic_len
+= job_len
+ 1;
391 if (basic_len
< (unsigned) columns()) {
392 unsigned extra_len
, incr
;
393 extra_len
= columns() - basic_len
;
395 /* Either UNIT already got 25, or is fully satisfied.
396 * Grant up to 25 to DESC now. */
397 incr
= MIN(extra_len
, 25u);
401 /* split the remaining space between UNIT and DESC,
402 * but do not give UNIT more than it needs. */
404 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
406 desc_len
+= extra_len
- incr
;
412 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
413 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
414 const char *on_loaded
= "", *off_loaded
= "";
415 const char *on_active
= "", *off_active
= "";
416 const char *on_circle
= "", *off_circle
= "";
420 if (!n_shown
&& !arg_no_legend
) {
425 printf("%-*s %-*s %-*s %-*s ",
428 active_len
, "ACTIVE",
432 printf("%-*s ", job_len
, "JOB");
434 if (!arg_full
&& arg_no_pager
)
435 printf("%.*s\n", desc_len
, "DESCRIPTION");
437 printf("%s\n", "DESCRIPTION");
442 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
443 on_loaded
= ansi_highlight_red();
444 on_circle
= ansi_highlight_yellow();
445 off_loaded
= off_circle
= ansi_normal();
447 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
448 on_circle
= on_active
= ansi_highlight_red();
449 off_circle
= off_active
= ansi_normal();
454 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
463 e
= ellipsize(id
, id_len
, 33);
471 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
473 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
474 on_active
, id_len
, id
, off_active
,
475 on_loaded
, load_len
, u
->load_state
, off_loaded
,
476 on_active
, active_len
, u
->active_state
,
477 sub_len
, u
->sub_state
, off_active
,
478 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
481 printf("%.*s\n", desc_len
, u
->description
);
483 printf("%s\n", u
->description
);
486 if (!arg_no_legend
) {
487 const char *on
, *off
;
491 "LOAD = Reflects whether the unit definition was properly loaded.\n"
492 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
493 "SUB = The low-level unit activation state, values depend on unit type.");
494 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
495 on
= ansi_highlight();
498 on
= ansi_highlight_red();
503 printf("%s%u loaded units listed.%s\n"
504 "To show all installed unit files use 'systemctl list-unit-files'.\n",
507 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
508 "To show all installed unit files use 'systemctl list-unit-files'.\n",
515 static int get_unit_list(
519 UnitInfo
**unit_infos
,
521 sd_bus_message
**_reply
) {
523 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
524 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
525 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
534 r
= sd_bus_message_new_method_call(
537 "org.freedesktop.systemd1",
538 "/org/freedesktop/systemd1",
539 "org.freedesktop.systemd1.Manager",
540 "ListUnitsFiltered");
543 return bus_log_create_error(r
);
545 r
= sd_bus_message_append_strv(m
, arg_states
);
547 return bus_log_create_error(r
);
549 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
551 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
553 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
555 return bus_log_parse_error(r
);
557 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
560 if (!output_show_unit(&u
, patterns
))
563 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
566 (*unit_infos
)[c
++] = u
;
569 return bus_log_parse_error(r
);
571 r
= sd_bus_message_exit_container(reply
);
573 return bus_log_parse_error(r
);
581 static void message_set_freep(Set
**set
) {
584 while ((m
= set_steal_first(*set
)))
585 sd_bus_message_unref(m
);
590 static int get_unit_list_recursive(
593 UnitInfo
**_unit_infos
,
597 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
598 _cleanup_(message_set_freep
) Set
*replies
;
599 sd_bus_message
*reply
;
607 replies
= set_new(NULL
);
611 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
615 r
= set_put(replies
, reply
);
617 sd_bus_message_unref(reply
);
622 _cleanup_strv_free_
char **machines
= NULL
;
625 r
= sd_get_machine_names(&machines
);
627 return log_error_errno(r
, "Failed to get machine names: %m");
629 STRV_FOREACH(i
, machines
) {
630 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
633 r
= sd_bus_open_system_machine(&container
, *i
);
635 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
639 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
645 r
= set_put(replies
, reply
);
647 sd_bus_message_unref(reply
);
652 *_machines
= machines
;
657 *_unit_infos
= unit_infos
;
666 static int list_units(int argc
, char *argv
[], void *userdata
) {
667 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
668 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
669 _cleanup_strv_free_
char **machines
= NULL
;
673 pager_open(arg_no_pager
, false);
675 r
= acquire_bus(BUS_MANAGER
, &bus
);
679 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
683 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
684 return output_units_list(unit_infos
, r
);
687 static int get_triggered_units(
692 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
699 r
= sd_bus_get_property_strv(
701 "org.freedesktop.systemd1",
703 "org.freedesktop.systemd1.Unit",
708 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
713 static int get_listening(
715 const char* unit_path
,
718 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
719 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
720 const char *type
, *path
;
723 r
= sd_bus_get_property(
725 "org.freedesktop.systemd1",
727 "org.freedesktop.systemd1.Socket",
733 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
735 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
737 return bus_log_parse_error(r
);
739 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
741 r
= strv_extend(listening
, type
);
745 r
= strv_extend(listening
, path
);
752 return bus_log_parse_error(r
);
754 r
= sd_bus_message_exit_container(reply
);
756 return bus_log_parse_error(r
);
768 /* Note: triggered is a list here, although it almost certainly
769 * will always be one unit. Nevertheless, dbus API allows for multiple
770 * values, so let's follow that. */
773 /* The strv above is shared. free is set only in the first one. */
777 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
783 if (!a
->machine
&& b
->machine
)
785 if (a
->machine
&& !b
->machine
)
787 if (a
->machine
&& b
->machine
) {
788 o
= strcasecmp(a
->machine
, b
->machine
);
793 o
= strcmp(a
->path
, b
->path
);
795 o
= strcmp(a
->type
, b
->type
);
800 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
801 struct socket_info
*s
;
802 unsigned pathlen
= strlen("LISTEN"),
803 typelen
= strlen("TYPE") * arg_show_types
,
804 socklen
= strlen("UNIT"),
805 servlen
= strlen("ACTIVATES");
806 const char *on
, *off
;
808 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
812 socklen
= MAX(socklen
, strlen(s
->id
));
814 typelen
= MAX(typelen
, strlen(s
->type
));
815 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
817 STRV_FOREACH(a
, s
->triggered
)
818 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
819 servlen
= MAX(servlen
, tmp
);
824 printf("%-*s %-*.*s%-*s %s\n",
826 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
830 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
831 _cleanup_free_
char *j
= NULL
;
836 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
844 printf("%-*s %-*s %-*s",
845 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
848 pathlen
, path
, socklen
, s
->id
);
849 STRV_FOREACH(a
, s
->triggered
)
851 a
== s
->triggered
? "" : ",", *a
);
855 on
= ansi_highlight();
860 on
= ansi_highlight_red();
864 if (!arg_no_legend
) {
865 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
867 printf("Pass --all to see loaded but inactive sockets, too.\n");
873 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
874 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
875 _cleanup_strv_free_
char **machines
= NULL
;
876 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
877 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
879 struct socket_info
*s
;
885 pager_open(arg_no_pager
, false);
887 r
= acquire_bus(BUS_MANAGER
, &bus
);
891 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
895 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
896 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
899 if (!endswith(u
->id
, ".socket"))
902 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
906 c
= get_listening(bus
, u
->unit_path
, &listening
);
912 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
917 for (i
= 0; i
< c
; i
++)
918 socket_infos
[cs
+ i
] = (struct socket_info
) {
919 .machine
= u
->machine
,
921 .type
= listening
[i
*2],
922 .path
= listening
[i
*2 + 1],
923 .triggered
= triggered
,
924 .own_triggered
= i
==0,
927 /* from this point on we will cleanup those socket_infos */
930 listening
= triggered
= NULL
; /* avoid cleanup */
933 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
934 (__compar_fn_t
) socket_info_compare
);
936 output_sockets_list(socket_infos
, cs
);
939 assert(cs
== 0 || socket_infos
);
940 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
943 if (s
->own_triggered
)
944 strv_free(s
->triggered
);
950 static int get_next_elapse(
953 dual_timestamp
*next
) {
955 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
963 r
= sd_bus_get_property_trivial(
965 "org.freedesktop.systemd1",
967 "org.freedesktop.systemd1.Timer",
968 "NextElapseUSecMonotonic",
973 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
975 r
= sd_bus_get_property_trivial(
977 "org.freedesktop.systemd1",
979 "org.freedesktop.systemd1.Timer",
980 "NextElapseUSecRealtime",
985 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
991 static int get_last_trigger(
996 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1003 r
= sd_bus_get_property_trivial(
1005 "org.freedesktop.systemd1",
1007 "org.freedesktop.systemd1.Timer",
1013 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1019 const char* machine
;
1022 usec_t last_trigger
;
1026 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1032 if (!a
->machine
&& b
->machine
)
1034 if (a
->machine
&& !b
->machine
)
1036 if (a
->machine
&& b
->machine
) {
1037 o
= strcasecmp(a
->machine
, b
->machine
);
1042 if (a
->next_elapse
< b
->next_elapse
)
1044 if (a
->next_elapse
> b
->next_elapse
)
1047 return strcmp(a
->id
, b
->id
);
1050 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1051 struct timer_info
*t
;
1053 nextlen
= strlen("NEXT"),
1054 leftlen
= strlen("LEFT"),
1055 lastlen
= strlen("LAST"),
1056 passedlen
= strlen("PASSED"),
1057 unitlen
= strlen("UNIT"),
1058 activatelen
= strlen("ACTIVATES");
1060 const char *on
, *off
;
1062 assert(timer_infos
|| n
== 0);
1064 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1068 if (t
->next_elapse
> 0) {
1069 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1071 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1072 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1074 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1075 leftlen
= MAX(leftlen
, strlen(trel
));
1078 if (t
->last_trigger
> 0) {
1079 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1081 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1082 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1084 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1085 passedlen
= MAX(passedlen
, strlen(trel
));
1088 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1090 STRV_FOREACH(a
, t
->triggered
)
1091 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1093 activatelen
= MAX(activatelen
, ul
);
1098 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1102 passedlen
, "PASSED",
1106 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1107 _cleanup_free_
char *j
= NULL
;
1109 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1110 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1113 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1114 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1116 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1117 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1120 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1127 printf("%-*s %-*s %-*s %-*s %-*s",
1128 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1130 STRV_FOREACH(a
, t
->triggered
)
1132 a
== t
->triggered
? "" : ",", *a
);
1136 on
= ansi_highlight();
1137 off
= ansi_normal();
1141 on
= ansi_highlight_red();
1142 off
= ansi_normal();
1145 if (!arg_no_legend
) {
1146 printf("%s%u timers listed.%s\n", on
, n
, off
);
1148 printf("Pass --all to see loaded but inactive timers, too.\n");
1154 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1160 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1163 if (next
->monotonic
> nw
->monotonic
)
1164 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1166 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1168 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1169 next_elapse
= MIN(converted
, next
->realtime
);
1171 next_elapse
= converted
;
1174 next_elapse
= next
->realtime
;
1179 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1180 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1181 _cleanup_strv_free_
char **machines
= NULL
;
1182 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1183 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1184 struct timer_info
*t
;
1192 pager_open(arg_no_pager
, false);
1194 r
= acquire_bus(BUS_MANAGER
, &bus
);
1198 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1202 dual_timestamp_get(&nw
);
1204 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1205 _cleanup_strv_free_
char **triggered
= NULL
;
1206 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1209 if (!endswith(u
->id
, ".timer"))
1212 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1216 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1220 get_last_trigger(bus
, u
->unit_path
, &last
);
1222 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1227 m
= calc_next_elapse(&nw
, &next
);
1229 timer_infos
[c
++] = (struct timer_info
) {
1230 .machine
= u
->machine
,
1233 .last_trigger
= last
,
1234 .triggered
= triggered
,
1237 triggered
= NULL
; /* avoid cleanup */
1240 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1241 (__compar_fn_t
) timer_info_compare
);
1243 output_timers_list(timer_infos
, c
);
1246 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1247 strv_free(t
->triggered
);
1252 static int compare_unit_file_list(const void *a
, const void *b
) {
1253 const char *d1
, *d2
;
1254 const UnitFileList
*u
= a
, *v
= b
;
1256 d1
= strrchr(u
->path
, '.');
1257 d2
= strrchr(v
->path
, '.');
1262 r
= strcasecmp(d1
, d2
);
1267 return strcasecmp(basename(u
->path
), basename(v
->path
));
1270 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1271 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1274 if (!strv_isempty(arg_types
)) {
1277 dot
= strrchr(u
->path
, '.');
1281 if (!strv_find(arg_types
, dot
+1))
1285 if (!strv_isempty(arg_states
) &&
1286 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1292 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1293 unsigned max_id_len
, id_cols
, state_cols
;
1294 const UnitFileList
*u
;
1296 max_id_len
= strlen("UNIT FILE");
1297 state_cols
= strlen("STATE");
1299 for (u
= units
; u
< units
+ c
; u
++) {
1300 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1301 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1305 unsigned basic_cols
;
1307 id_cols
= MIN(max_id_len
, 25u);
1308 basic_cols
= 1 + id_cols
+ state_cols
;
1309 if (basic_cols
< (unsigned) columns())
1310 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1312 id_cols
= max_id_len
;
1315 printf("%-*s %-*s\n",
1316 id_cols
, "UNIT FILE",
1317 state_cols
, "STATE");
1319 for (u
= units
; u
< units
+ c
; u
++) {
1320 _cleanup_free_
char *e
= NULL
;
1321 const char *on
, *off
;
1324 if (IN_SET(u
->state
,
1326 UNIT_FILE_MASKED_RUNTIME
,
1329 on
= ansi_highlight_red();
1330 off
= ansi_normal();
1331 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1332 on
= ansi_highlight_green();
1333 off
= ansi_normal();
1337 id
= basename(u
->path
);
1339 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1341 printf("%-*s %s%-*s%s\n",
1342 id_cols
, e
? e
: id
,
1343 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1347 printf("\n%u unit files listed.\n", c
);
1350 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1351 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1352 _cleanup_free_ UnitFileList
*units
= NULL
;
1360 pager_open(arg_no_pager
, false);
1362 if (install_client_side()) {
1368 h
= hashmap_new(&string_hash_ops
);
1372 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1374 unit_file_list_free(h
);
1375 return log_error_errno(r
, "Failed to get unit file list: %m");
1378 n_units
= hashmap_size(h
);
1380 units
= new(UnitFileList
, n_units
);
1381 if (!units
&& n_units
> 0) {
1382 unit_file_list_free(h
);
1386 HASHMAP_FOREACH(u
, h
, i
) {
1387 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1394 assert(c
<= n_units
);
1397 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1400 r
= acquire_bus(BUS_MANAGER
, &bus
);
1404 r
= sd_bus_call_method(
1406 "org.freedesktop.systemd1",
1407 "/org/freedesktop/systemd1",
1408 "org.freedesktop.systemd1.Manager",
1414 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1416 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1418 return bus_log_parse_error(r
);
1420 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1422 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1425 units
[c
] = (struct UnitFileList
) {
1427 unit_file_state_from_string(state
)
1430 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1435 return bus_log_parse_error(r
);
1437 r
= sd_bus_message_exit_container(reply
);
1439 return bus_log_parse_error(r
);
1442 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1443 output_unit_file_list(units
, c
);
1445 if (install_client_side()) {
1446 for (unit
= units
; unit
< units
+ c
; unit
++)
1453 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1454 _cleanup_free_
char *n
= NULL
;
1455 size_t max_len
= MAX(columns(),20u);
1461 for (i
= level
- 1; i
>= 0; i
--) {
1463 if (len
> max_len
- 3 && !arg_full
) {
1464 printf("%s...\n",max_len
% 2 ? "" : " ");
1467 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1471 if (len
> max_len
- 3 && !arg_full
) {
1472 printf("%s...\n",max_len
% 2 ? "" : " ");
1476 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1480 printf("%s\n", name
);
1484 n
= ellipsize(name
, max_len
-len
, 100);
1492 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1494 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1495 [DEPENDENCY_FORWARD
] = "Requires\0"
1500 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1505 [DEPENDENCY_AFTER
] = "After\0",
1506 [DEPENDENCY_BEFORE
] = "Before\0",
1509 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1510 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1511 _cleanup_strv_free_
char **ret
= NULL
;
1512 _cleanup_free_
char *path
= NULL
;
1518 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1520 path
= unit_dbus_path_from_name(name
);
1524 r
= sd_bus_call_method(
1526 "org.freedesktop.systemd1",
1528 "org.freedesktop.DBus.Properties",
1532 "s", "org.freedesktop.systemd1.Unit");
1534 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1536 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1538 return bus_log_parse_error(r
);
1540 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1543 r
= sd_bus_message_read(reply
, "s", &prop
);
1545 return bus_log_parse_error(r
);
1547 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1548 r
= sd_bus_message_skip(reply
, "v");
1550 return bus_log_parse_error(r
);
1553 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1555 return bus_log_parse_error(r
);
1557 r
= bus_message_read_strv_extend(reply
, &ret
);
1559 return bus_log_parse_error(r
);
1561 r
= sd_bus_message_exit_container(reply
);
1563 return bus_log_parse_error(r
);
1566 r
= sd_bus_message_exit_container(reply
);
1568 return bus_log_parse_error(r
);
1572 return bus_log_parse_error(r
);
1574 r
= sd_bus_message_exit_container(reply
);
1576 return bus_log_parse_error(r
);
1584 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1585 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1587 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1589 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1592 return strcasecmp(*a
, *b
);
1595 static int list_dependencies_one(
1600 unsigned int branches
) {
1602 _cleanup_strv_free_
char **deps
= NULL
;
1610 r
= strv_extend(units
, name
);
1614 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1618 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1620 STRV_FOREACH(c
, deps
) {
1621 if (strv_contains(*units
, *c
)) {
1623 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1633 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1636 (void) get_state_one_unit(bus
, *c
, &active_state
);
1637 switch (active_state
) {
1639 case UNIT_RELOADING
:
1640 case UNIT_ACTIVATING
:
1641 on
= ansi_highlight_green();
1645 case UNIT_DEACTIVATING
:
1650 on
= ansi_highlight_red();
1654 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1657 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1661 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1662 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1669 strv_remove(*units
, name
);
1674 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1675 _cleanup_strv_free_
char **units
= NULL
;
1676 _cleanup_free_
char *unit
= NULL
;
1682 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1684 return log_error_errno(r
, "Failed to mangle unit name: %m");
1688 u
= SPECIAL_DEFAULT_TARGET
;
1690 pager_open(arg_no_pager
, false);
1692 r
= acquire_bus(BUS_MANAGER
, &bus
);
1698 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1701 struct machine_info
{
1705 char *control_group
;
1706 uint32_t n_failed_units
;
1711 static const struct bus_properties_map machine_info_property_map
[] = {
1712 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1713 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1714 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1715 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1716 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1720 static void machine_info_clear(struct machine_info
*info
) {
1724 free(info
->control_group
);
1729 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1735 for (i
= 0; i
< n
; i
++)
1736 machine_info_clear(&machine_infos
[i
]);
1738 free(machine_infos
);
1741 static int compare_machine_info(const void *a
, const void *b
) {
1742 const struct machine_info
*u
= a
, *v
= b
;
1744 if (u
->is_host
!= v
->is_host
)
1745 return u
->is_host
> v
->is_host
? -1 : 1;
1747 return strcasecmp(u
->name
, v
->name
);
1750 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1751 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1757 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1764 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1771 static bool output_show_machine(const char *name
, char **patterns
) {
1772 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1775 static int get_machine_list(
1777 struct machine_info
**_machine_infos
,
1780 struct machine_info
*machine_infos
= NULL
;
1781 _cleanup_strv_free_
char **m
= NULL
;
1782 _cleanup_free_
char *hn
= NULL
;
1787 hn
= gethostname_malloc();
1791 if (output_show_machine(hn
, patterns
)) {
1792 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1795 machine_infos
[c
].is_host
= true;
1796 machine_infos
[c
].name
= hn
;
1799 get_machine_properties(bus
, &machine_infos
[c
]);
1803 r
= sd_get_machine_names(&m
);
1805 return log_error_errno(r
, "Failed to get machine list: %m");
1807 STRV_FOREACH(i
, m
) {
1808 _cleanup_free_
char *class = NULL
;
1810 if (!output_show_machine(*i
, patterns
))
1813 sd_machine_get_class(*i
, &class);
1814 if (!streq_ptr(class, "container"))
1817 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1818 free_machines_list(machine_infos
, c
);
1822 machine_infos
[c
].is_host
= false;
1823 machine_infos
[c
].name
= strdup(*i
);
1824 if (!machine_infos
[c
].name
) {
1825 free_machines_list(machine_infos
, c
);
1829 get_machine_properties(NULL
, &machine_infos
[c
]);
1833 *_machine_infos
= machine_infos
;
1837 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1838 struct machine_info
*m
;
1841 namelen
= sizeof("NAME") - 1,
1842 statelen
= sizeof("STATE") - 1,
1843 failedlen
= sizeof("FAILED") - 1,
1844 jobslen
= sizeof("JOBS") - 1;
1846 assert(machine_infos
|| n
== 0);
1848 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1849 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1850 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1851 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1852 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1854 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1858 if (!arg_no_legend
) {
1862 printf("%-*s %-*s %-*s %-*s\n",
1865 failedlen
, "FAILED",
1869 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1870 const char *on_state
= "", *off_state
= "";
1871 const char *on_failed
= "", *off_failed
= "";
1872 bool circle
= false;
1874 if (streq_ptr(m
->state
, "degraded")) {
1875 on_state
= ansi_highlight_red();
1876 off_state
= ansi_normal();
1878 } else if (!streq_ptr(m
->state
, "running")) {
1879 on_state
= ansi_highlight_yellow();
1880 off_state
= ansi_normal();
1884 if (m
->n_failed_units
> 0) {
1885 on_failed
= ansi_highlight_red();
1886 off_failed
= ansi_normal();
1888 on_failed
= off_failed
= "";
1891 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1894 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1895 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1896 on_state
, statelen
, strna(m
->state
), off_state
,
1897 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1898 jobslen
, m
->n_jobs
);
1900 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1901 namelen
, strna(m
->name
),
1902 on_state
, statelen
, strna(m
->state
), off_state
,
1903 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1904 jobslen
, m
->n_jobs
);
1908 printf("\n%u machines listed.\n", n
);
1911 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1912 struct machine_info
*machine_infos
= NULL
;
1916 if (geteuid() != 0) {
1917 log_error("Must be root.");
1921 pager_open(arg_no_pager
, false);
1923 r
= acquire_bus(BUS_MANAGER
, &bus
);
1927 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1931 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1932 output_machines_list(machine_infos
, r
);
1933 free_machines_list(machine_infos
, r
);
1938 static int get_default(int argc
, char *argv
[], void *userdata
) {
1939 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1940 _cleanup_free_
char *_path
= NULL
;
1944 if (install_client_side()) {
1945 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1947 return log_error_errno(r
, "Failed to get default target: %m");
1951 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1954 r
= acquire_bus(BUS_MANAGER
, &bus
);
1958 r
= sd_bus_call_method(
1960 "org.freedesktop.systemd1",
1961 "/org/freedesktop/systemd1",
1962 "org.freedesktop.systemd1.Manager",
1968 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1970 r
= sd_bus_message_read(reply
, "s", &path
);
1972 return bus_log_parse_error(r
);
1976 printf("%s\n", path
);
1981 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1984 assert(changes
|| n_changes
== 0);
1986 for (i
= 0; i
< n_changes
; i
++) {
1987 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1988 log_info("Created symlink %s, pointing to %s.", changes
[i
].path
, changes
[i
].source
);
1990 log_info("Removed symlink %s.", changes
[i
].path
);
1994 static int set_default(int argc
, char *argv
[], void *userdata
) {
1995 _cleanup_free_
char *unit
= NULL
;
2001 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2003 return log_error_errno(r
, "Failed to mangle unit name: %m");
2005 if (install_client_side()) {
2006 UnitFileChange
*changes
= NULL
;
2007 unsigned n_changes
= 0;
2009 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2011 return log_error_errno(r
, "Failed to set default target: %m");
2014 dump_unit_file_changes(changes
, n_changes
);
2016 unit_file_changes_free(changes
, n_changes
);
2019 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2020 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2023 polkit_agent_open_if_enabled();
2025 r
= acquire_bus(BUS_MANAGER
, &bus
);
2029 r
= sd_bus_call_method(
2031 "org.freedesktop.systemd1",
2032 "/org/freedesktop/systemd1",
2033 "org.freedesktop.systemd1.Manager",
2039 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2041 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2045 /* Try to reload if enabled */
2047 r
= daemon_reload(argc
, argv
, userdata
);
2057 const char *name
, *type
, *state
;
2060 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2061 unsigned id_len
, unit_len
, type_len
, state_len
;
2062 const struct job_info
*j
;
2063 const char *on
, *off
;
2064 bool shorten
= false;
2066 assert(n
== 0 || jobs
);
2069 if (!arg_no_legend
) {
2070 on
= ansi_highlight_green();
2071 off
= ansi_normal();
2073 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2078 pager_open(arg_no_pager
, false);
2080 id_len
= strlen("JOB");
2081 unit_len
= strlen("UNIT");
2082 type_len
= strlen("TYPE");
2083 state_len
= strlen("STATE");
2085 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2086 uint32_t id
= j
->id
;
2087 assert(j
->name
&& j
->type
&& j
->state
);
2089 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2090 unit_len
= MAX(unit_len
, strlen(j
->name
));
2091 type_len
= MAX(type_len
, strlen(j
->type
));
2092 state_len
= MAX(state_len
, strlen(j
->state
));
2095 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2096 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2101 printf("%*s %-*s %-*s %-*s\n",
2105 state_len
, "STATE");
2107 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2108 _cleanup_free_
char *e
= NULL
;
2110 if (streq(j
->state
, "running")) {
2111 on
= ansi_highlight();
2112 off
= ansi_normal();
2116 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2117 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2119 on
, unit_len
, e
? e
: j
->name
, off
,
2121 on
, state_len
, j
->state
, off
);
2124 if (!arg_no_legend
) {
2125 on
= ansi_highlight();
2126 off
= ansi_normal();
2128 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2132 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2133 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2136 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2137 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2138 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2139 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2140 _cleanup_free_
struct job_info
*jobs
= NULL
;
2146 bool skipped
= false;
2148 pager_open(arg_no_pager
, false);
2150 r
= acquire_bus(BUS_MANAGER
, &bus
);
2154 r
= sd_bus_call_method(
2156 "org.freedesktop.systemd1",
2157 "/org/freedesktop/systemd1",
2158 "org.freedesktop.systemd1.Manager",
2164 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2166 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2168 return bus_log_parse_error(r
);
2170 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2171 struct job_info job
= { id
, name
, type
, state
};
2173 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2178 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2184 return bus_log_parse_error(r
);
2186 r
= sd_bus_message_exit_container(reply
);
2188 return bus_log_parse_error(r
);
2190 output_jobs_list(jobs
, c
, skipped
);
2194 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2200 return daemon_reload(argc
, argv
, userdata
);
2202 polkit_agent_open_if_enabled();
2204 r
= acquire_bus(BUS_MANAGER
, &bus
);
2208 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2209 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2213 q
= safe_atou32(*name
, &id
);
2215 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2217 q
= sd_bus_call_method(
2219 "org.freedesktop.systemd1",
2220 "/org/freedesktop/systemd1",
2221 "org.freedesktop.systemd1.Manager",
2227 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2236 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2237 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2241 /* We ignore all errors here, since this is used to show a
2244 /* We don't use unit_dbus_path_from_name() directly since we
2245 * don't want to load the unit if it isn't loaded. */
2247 r
= sd_bus_call_method(
2249 "org.freedesktop.systemd1",
2250 "/org/freedesktop/systemd1",
2251 "org.freedesktop.systemd1.Manager",
2259 r
= sd_bus_message_read(reply
, "o", &path
);
2263 r
= sd_bus_get_property_trivial(
2265 "org.freedesktop.systemd1",
2267 "org.freedesktop.systemd1.Unit",
2277 static void warn_unit_file_changed(const char *name
) {
2278 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2279 ansi_highlight_red(),
2282 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2285 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2292 STRV_FOREACH(p
, lp
->unit_path
) {
2293 _cleanup_free_
char *path
;
2295 path
= path_join(arg_root
, *p
, unit_name
);
2299 if (access(path
, F_OK
) == 0) {
2309 static int unit_find_paths(
2311 const char *unit_name
,
2313 char **fragment_path
,
2314 char ***dropin_paths
) {
2316 _cleanup_free_
char *path
= NULL
;
2317 _cleanup_strv_free_
char **dropins
= NULL
;
2321 * Finds where the unit is defined on disk. Returns 0 if the unit
2322 * is not found. Returns 1 if it is found, and sets
2323 * - the path to the unit in *path, if it exists on disk,
2324 * - and a strv of existing drop-ins in *dropins,
2325 * if the arg is not NULL and any dropins were found.
2329 assert(fragment_path
);
2332 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2333 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2334 _cleanup_free_
char *unit
= NULL
;
2336 unit
= unit_dbus_path_from_name(unit_name
);
2340 r
= sd_bus_get_property_string(
2342 "org.freedesktop.systemd1",
2344 "org.freedesktop.systemd1.Unit",
2349 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2352 r
= sd_bus_get_property_strv(
2354 "org.freedesktop.systemd1",
2356 "org.freedesktop.systemd1.Unit",
2361 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2364 _cleanup_set_free_ Set
*names
;
2366 names
= set_new(NULL
);
2370 r
= set_put(names
, unit_name
);
2372 return log_error_errno(r
, "Failed to add unit name: %m");
2374 r
= unit_file_find_path(lp
, unit_name
, &path
);
2379 _cleanup_free_
char *template = NULL
;
2381 r
= unit_name_template(unit_name
, &template);
2382 if (r
< 0 && r
!= -EINVAL
)
2383 return log_error_errno(r
, "Failed to determine template name: %m");
2385 r
= unit_file_find_path(lp
, template, &path
);
2392 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2400 if (!isempty(path
)) {
2401 *fragment_path
= path
;
2406 if (dropin_paths
&& !strv_isempty(dropins
)) {
2407 *dropin_paths
= dropins
;
2413 log_error("No files found for %s.", unit_name
);
2418 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2419 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2420 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2421 _cleanup_free_
char *buf
= NULL
;
2422 UnitActiveState state
;
2427 assert(active_state
);
2429 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2431 r
= sd_bus_call_method(
2433 "org.freedesktop.systemd1",
2434 "/org/freedesktop/systemd1",
2435 "org.freedesktop.systemd1.Manager",
2441 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2442 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2444 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2445 * considered inactive. */
2446 state
= UNIT_INACTIVE
;
2449 r
= sd_bus_message_read(reply
, "o", &path
);
2451 return bus_log_parse_error(r
);
2453 r
= sd_bus_get_property_string(
2455 "org.freedesktop.systemd1",
2457 "org.freedesktop.systemd1.Unit",
2462 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2464 state
= unit_active_state_from_string(buf
);
2465 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2466 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2471 *active_state
= state
;
2475 static int check_triggering_units(
2479 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2480 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2481 _cleanup_strv_free_
char **triggered_by
= NULL
;
2482 bool print_warning_label
= true;
2483 UnitActiveState active_state
;
2487 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2489 return log_error_errno(r
, "Failed to mangle unit name: %m");
2491 path
= unit_dbus_path_from_name(n
);
2495 r
= sd_bus_get_property_string(
2497 "org.freedesktop.systemd1",
2499 "org.freedesktop.systemd1.Unit",
2504 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2506 if (streq(load_state
, "masked"))
2509 r
= sd_bus_get_property_strv(
2511 "org.freedesktop.systemd1",
2513 "org.freedesktop.systemd1.Unit",
2518 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2520 STRV_FOREACH(i
, triggered_by
) {
2521 r
= get_state_one_unit(bus
, *i
, &active_state
);
2525 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2528 if (print_warning_label
) {
2529 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2530 print_warning_label
= false;
2533 log_warning(" %s", *i
);
2539 static const struct {
2542 } unit_actions
[] = {
2543 { "start", "StartUnit" },
2544 { "stop", "StopUnit" },
2545 { "condstop", "StopUnit" },
2546 { "reload", "ReloadUnit" },
2547 { "restart", "RestartUnit" },
2548 { "try-restart", "TryRestartUnit" },
2549 { "condrestart", "TryRestartUnit" },
2550 { "reload-or-restart", "ReloadOrRestartUnit" },
2551 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2552 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2553 { "condreload", "ReloadOrTryRestartUnit" },
2554 { "force-reload", "ReloadOrTryRestartUnit" }
2557 static const char *verb_to_method(const char *verb
) {
2560 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2561 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2562 return unit_actions
[i
].method
;
2567 static const char *method_to_verb(const char *method
) {
2570 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2571 if (streq_ptr(unit_actions
[i
].method
, method
))
2572 return unit_actions
[i
].verb
;
2577 static int start_unit_one(
2582 sd_bus_error
*error
,
2583 BusWaitForJobs
*w
) {
2585 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2594 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2596 r
= sd_bus_call_method(
2598 "org.freedesktop.systemd1",
2599 "/org/freedesktop/systemd1",
2600 "org.freedesktop.systemd1.Manager",
2608 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2609 /* There's always a fallback possible for
2610 * legacy actions. */
2611 return -EADDRNOTAVAIL
;
2613 verb
= method_to_verb(method
);
2615 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2617 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2618 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2619 log_error("See %s logs and 'systemctl%s status %s' for details.",
2620 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2621 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2627 r
= sd_bus_message_read(reply
, "o", &path
);
2629 return bus_log_parse_error(r
);
2631 if (need_daemon_reload(bus
, name
) > 0)
2632 warn_unit_file_changed(name
);
2635 log_debug("Adding %s to the set", path
);
2636 r
= bus_wait_for_jobs_add(w
, path
);
2644 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2645 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2652 STRV_FOREACH(name
, names
) {
2656 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2658 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2660 return log_error_errno(r
, "Failed to mangle name: %m");
2662 if (string_is_glob(t
))
2663 r
= strv_consume(&globs
, t
);
2665 r
= strv_consume(&mangled
, t
);
2670 /* Query the manager only if any of the names are a glob, since
2671 * this is fairly expensive */
2672 if (!strv_isempty(globs
)) {
2673 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2674 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2675 size_t allocated
, n
;
2677 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2681 n
= strv_length(mangled
);
2684 for (i
= 0; i
< r
; i
++) {
2685 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2688 mangled
[n
] = strdup(unit_infos
[i
].id
);
2692 mangled
[++n
] = NULL
;
2697 mangled
= NULL
; /* do not free */
2702 static const struct {
2706 } action_table
[_ACTION_MAX
] = {
2707 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2708 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2709 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2710 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2711 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2712 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2713 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2714 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2715 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2716 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2717 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2718 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2719 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2720 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2721 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2724 static enum action
verb_to_action(const char *verb
) {
2727 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2728 if (streq_ptr(action_table
[i
].verb
, verb
))
2731 return _ACTION_INVALID
;
2734 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2735 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2736 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2737 _cleanup_strv_free_
char **names
= NULL
;
2742 ask_password_agent_open_if_enabled();
2743 polkit_agent_open_if_enabled();
2745 r
= acquire_bus(BUS_MANAGER
, &bus
);
2749 if (arg_action
== ACTION_SYSTEMCTL
) {
2752 method
= verb_to_method(argv
[0]);
2753 action
= verb_to_action(argv
[0]);
2755 if (streq(argv
[0], "isolate")) {
2759 mode
= action_table
[action
].mode
?: arg_job_mode
;
2761 one_name
= action_table
[action
].target
;
2763 assert(arg_action
< ELEMENTSOF(action_table
));
2764 assert(action_table
[arg_action
].target
);
2766 method
= "StartUnit";
2768 mode
= action_table
[arg_action
].mode
;
2769 one_name
= action_table
[arg_action
].target
;
2773 names
= strv_new(one_name
, NULL
);
2775 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2777 return log_error_errno(r
, "Failed to expand names: %m");
2780 if (!arg_no_block
) {
2781 r
= bus_wait_for_jobs_new(bus
, &w
);
2783 return log_error_errno(r
, "Could not watch jobs: %m");
2786 STRV_FOREACH(name
, names
) {
2787 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2790 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2791 if (r
>= 0 && q
< 0)
2792 r
= translate_bus_error_to_exit_status(q
, &error
);
2795 if (!arg_no_block
) {
2796 int q
, arg_count
= 0;
2797 const char* extra_args
[4] = {};
2799 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2800 extra_args
[arg_count
++] = "--user";
2802 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2803 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2804 extra_args
[arg_count
++] = "-H";
2805 extra_args
[arg_count
++] = arg_host
;
2806 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2807 extra_args
[arg_count
++] = "-M";
2808 extra_args
[arg_count
++] = arg_host
;
2811 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2815 /* When stopping units, warn if they can still be triggered by
2816 * another active unit (socket, path, timer) */
2817 if (!arg_quiet
&& streq(method
, "StopUnit"))
2818 STRV_FOREACH(name
, names
)
2819 check_triggering_units(bus
, *name
);
2825 static int logind_set_wall_message(void) {
2827 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2829 _cleanup_free_
char *m
= NULL
;
2832 r
= acquire_bus(BUS_FULL
, &bus
);
2836 m
= strv_join(arg_wall
, " ");
2840 r
= sd_bus_call_method(
2842 "org.freedesktop.login1",
2843 "/org/freedesktop/login1",
2844 "org.freedesktop.login1.Manager",
2853 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2859 /* Ask systemd-logind, which might grant access to unprivileged users
2860 * through PolicyKit */
2861 static int logind_reboot(enum action a
) {
2863 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2864 const char *method
, *description
;
2868 polkit_agent_open_if_enabled();
2869 (void) logind_set_wall_message();
2871 r
= acquire_bus(BUS_FULL
, &bus
);
2879 description
= "reboot system";
2882 case ACTION_POWEROFF
:
2883 method
= "PowerOff";
2884 description
= "power off system";
2887 case ACTION_SUSPEND
:
2889 description
= "suspend system";
2892 case ACTION_HIBERNATE
:
2893 method
= "Hibernate";
2894 description
= "hibernate system";
2897 case ACTION_HYBRID_SLEEP
:
2898 method
= "HybridSleep";
2899 description
= "put system into hybrid sleep";
2906 r
= sd_bus_call_method(
2908 "org.freedesktop.login1",
2909 "/org/freedesktop/login1",
2910 "org.freedesktop.login1.Manager",
2914 "b", arg_ask_password
);
2916 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2924 static int logind_check_inhibitors(enum action a
) {
2926 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2927 _cleanup_strv_free_
char **sessions
= NULL
;
2928 const char *what
, *who
, *why
, *mode
;
2935 if (arg_ignore_inhibitors
|| arg_force
> 0)
2947 r
= acquire_bus(BUS_FULL
, &bus
);
2951 r
= sd_bus_call_method(
2953 "org.freedesktop.login1",
2954 "/org/freedesktop/login1",
2955 "org.freedesktop.login1.Manager",
2961 /* If logind is not around, then there are no inhibitors... */
2964 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2966 return bus_log_parse_error(r
);
2968 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2969 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2970 _cleanup_strv_free_
char **sv
= NULL
;
2972 if (!streq(mode
, "block"))
2975 sv
= strv_split(what
, ":");
2979 if ((pid_t
) pid
< 0)
2980 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2982 if (!strv_contains(sv
,
2987 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2990 get_process_comm(pid
, &comm
);
2991 user
= uid_to_name(uid
);
2993 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2994 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2999 return bus_log_parse_error(r
);
3001 r
= sd_bus_message_exit_container(reply
);
3003 return bus_log_parse_error(r
);
3005 /* Check for current sessions */
3006 sd_get_sessions(&sessions
);
3007 STRV_FOREACH(s
, sessions
) {
3008 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3010 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3013 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3016 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3019 sd_session_get_tty(*s
, &tty
);
3020 sd_session_get_seat(*s
, &seat
);
3021 sd_session_get_service(*s
, &service
);
3022 user
= uid_to_name(uid
);
3024 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3031 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3032 action_table
[a
].verb
);
3040 static int logind_prepare_firmware_setup(void) {
3042 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3046 r
= acquire_bus(BUS_FULL
, &bus
);
3050 r
= sd_bus_call_method(
3052 "org.freedesktop.login1",
3053 "/org/freedesktop/login1",
3054 "org.freedesktop.login1.Manager",
3055 "SetRebootToFirmwareSetup",
3060 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3064 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3069 static int prepare_firmware_setup(void) {
3072 if (!arg_firmware_setup
)
3075 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3077 r
= efi_set_reboot_to_firmware(true);
3079 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3084 return logind_prepare_firmware_setup();
3087 static int set_exit_code(uint8_t code
) {
3088 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3092 r
= acquire_bus(BUS_MANAGER
, &bus
);
3096 r
= sd_bus_call_method(
3098 "org.freedesktop.systemd1",
3099 "/org/freedesktop/systemd1",
3100 "org.freedesktop.systemd1.Manager",
3106 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3111 static int start_special(int argc
, char *argv
[], void *userdata
) {
3117 a
= verb_to_action(argv
[0]);
3119 r
= logind_check_inhibitors(a
);
3123 if (arg_force
>= 2 && geteuid() != 0) {
3124 log_error("Must be root.");
3128 r
= prepare_firmware_setup();
3132 if (a
== ACTION_REBOOT
&& argc
> 1) {
3133 r
= update_reboot_param_file(argv
[1]);
3137 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3140 /* If the exit code is not given on the command line,
3141 * don't reset it to zero: just keep it as it might
3142 * have been set previously. */
3144 r
= safe_atou8(argv
[1], &code
);
3146 return log_error_errno(r
, "Invalid exit code.");
3148 r
= set_exit_code(code
);
3153 if (arg_force
>= 2 &&
3160 if (arg_force
>= 1 &&
3167 return daemon_reload(argc
, argv
, userdata
);
3169 /* First try logind, to allow authentication with polkit */
3175 ACTION_HYBRID_SLEEP
)) {
3176 r
= logind_reboot(a
);
3179 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3180 /* requested operation is not supported or already in progress */
3183 /* On all other errors, try low-level operation */
3186 return start_unit(argc
, argv
, userdata
);
3189 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3190 _cleanup_strv_free_
char **names
= NULL
;
3191 UnitActiveState active_state
;
3197 r
= acquire_bus(BUS_MANAGER
, &bus
);
3201 r
= expand_names(bus
, args
, NULL
, &names
);
3203 return log_error_errno(r
, "Failed to expand names: %m");
3205 STRV_FOREACH(name
, names
) {
3206 r
= get_state_one_unit(bus
, *name
, &active_state
);
3211 puts(unit_active_state_to_string(active_state
));
3213 for (i
= 0; i
< nb_states
; ++i
)
3214 if (good_states
[i
] == active_state
)
3218 /* use the given return code for the case that we won't find
3219 * any unit which matches the list */
3220 return found
? 0 : code
;
3223 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3224 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3225 /* According to LSB: 3, "program is not running" */
3226 return check_unit_generic(3, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3229 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3230 const UnitActiveState states
[] = { UNIT_FAILED
};
3231 return check_unit_generic(1, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3234 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3235 _cleanup_strv_free_
char **names
= NULL
;
3236 char *kill_who
= NULL
, **name
;
3240 polkit_agent_open_if_enabled();
3242 r
= acquire_bus(BUS_MANAGER
, &bus
);
3247 arg_kill_who
= "all";
3249 /* --fail was specified */
3250 if (streq(arg_job_mode
, "fail"))
3251 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3253 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3255 return log_error_errno(r
, "Failed to expand names: %m");
3257 STRV_FOREACH(name
, names
) {
3258 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3260 q
= sd_bus_call_method(
3262 "org.freedesktop.systemd1",
3263 "/org/freedesktop/systemd1",
3264 "org.freedesktop.systemd1.Manager",
3268 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3270 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3279 typedef struct ExecStatusInfo
{
3287 usec_t start_timestamp
;
3288 usec_t exit_timestamp
;
3293 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3296 static void exec_status_info_free(ExecStatusInfo
*i
) {
3305 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3306 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3309 int32_t code
, status
;
3315 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3317 return bus_log_parse_error(r
);
3321 r
= sd_bus_message_read(m
, "s", &path
);
3323 return bus_log_parse_error(r
);
3325 i
->path
= strdup(path
);
3329 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3331 return bus_log_parse_error(r
);
3333 r
= sd_bus_message_read(m
,
3336 &start_timestamp
, &start_timestamp_monotonic
,
3337 &exit_timestamp
, &exit_timestamp_monotonic
,
3341 return bus_log_parse_error(r
);
3344 i
->start_timestamp
= (usec_t
) start_timestamp
;
3345 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3346 i
->pid
= (pid_t
) pid
;
3350 r
= sd_bus_message_exit_container(m
);
3352 return bus_log_parse_error(r
);
3357 typedef struct UnitStatusInfo
{
3359 const char *load_state
;
3360 const char *active_state
;
3361 const char *sub_state
;
3362 const char *unit_file_state
;
3363 const char *unit_file_preset
;
3365 const char *description
;
3366 const char *following
;
3368 char **documentation
;
3370 const char *fragment_path
;
3371 const char *source_path
;
3372 const char *control_group
;
3374 char **dropin_paths
;
3376 const char *load_error
;
3379 usec_t inactive_exit_timestamp
;
3380 usec_t inactive_exit_timestamp_monotonic
;
3381 usec_t active_enter_timestamp
;
3382 usec_t active_exit_timestamp
;
3383 usec_t inactive_enter_timestamp
;
3385 bool need_daemon_reload
;
3391 const char *status_text
;
3392 const char *pid_file
;
3396 usec_t start_timestamp
;
3397 usec_t exit_timestamp
;
3399 int exit_code
, exit_status
;
3401 usec_t condition_timestamp
;
3402 bool condition_result
;
3403 bool failed_condition_trigger
;
3404 bool failed_condition_negate
;
3405 const char *failed_condition
;
3406 const char *failed_condition_parameter
;
3408 usec_t assert_timestamp
;
3410 bool failed_assert_trigger
;
3411 bool failed_assert_negate
;
3412 const char *failed_assert
;
3413 const char *failed_assert_parameter
;
3416 unsigned n_accepted
;
3417 unsigned n_connections
;
3420 /* Pairs of type, path */
3424 const char *sysfs_path
;
3426 /* Mount, Automount */
3433 uint64_t memory_current
;
3434 uint64_t memory_limit
;
3435 uint64_t cpu_usage_nsec
;
3436 uint64_t tasks_current
;
3439 LIST_HEAD(ExecStatusInfo
, exec
);
3442 static void print_status_info(
3447 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3449 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3450 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3456 /* This shows pretty information about a unit. See
3457 * print_property() for a low-level property printer */
3459 if (streq_ptr(i
->active_state
, "failed")) {
3460 active_on
= ansi_highlight_red();
3461 active_off
= ansi_normal();
3462 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3463 active_on
= ansi_highlight_green();
3464 active_off
= ansi_normal();
3466 active_on
= active_off
= "";
3468 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3470 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3471 printf(" - %s", i
->description
);
3476 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3478 if (streq_ptr(i
->load_state
, "error")) {
3479 on
= ansi_highlight_red();
3480 off
= ansi_normal();
3484 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3486 if (i
->load_error
!= 0)
3487 printf(" Loaded: %s%s%s (Reason: %s)\n",
3488 on
, strna(i
->load_state
), off
, i
->load_error
);
3489 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3490 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3491 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3492 else if (path
&& !isempty(i
->unit_file_state
))
3493 printf(" Loaded: %s%s%s (%s; %s)\n",
3494 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3496 printf(" Loaded: %s%s%s (%s)\n",
3497 on
, strna(i
->load_state
), off
, path
);
3499 printf(" Loaded: %s%s%s\n",
3500 on
, strna(i
->load_state
), off
);
3503 printf("Transient: yes\n");
3505 if (!strv_isempty(i
->dropin_paths
)) {
3506 _cleanup_free_
char *dir
= NULL
;
3510 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3511 if (! dir
|| last
) {
3512 printf(dir
? " " : " Drop-In: ");
3516 dir
= dirname_malloc(*dropin
);
3522 printf("%s\n %s", dir
,
3523 draw_special_char(DRAW_TREE_RIGHT
));
3526 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3528 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3532 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3534 printf(" Active: %s%s (%s)%s",
3535 active_on
, strna(i
->active_state
), ss
, active_off
);
3537 printf(" Active: %s%s%s",
3538 active_on
, strna(i
->active_state
), active_off
);
3540 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3541 printf(" (Result: %s)", i
->result
);
3543 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3544 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3545 (streq_ptr(i
->active_state
, "inactive") ||
3546 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3547 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3548 i
->active_exit_timestamp
;
3550 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3551 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3554 printf(" since %s; %s\n", s2
, s1
);
3556 printf(" since %s\n", s2
);
3560 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3561 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3562 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3564 printf("Condition: start %scondition failed%s at %s%s%s\n",
3565 ansi_highlight_yellow(), ansi_normal(),
3566 s2
, s1
? "; " : "", strempty(s1
));
3567 if (i
->failed_condition_trigger
)
3568 printf(" none of the trigger conditions were met\n");
3569 else if (i
->failed_condition
)
3570 printf(" %s=%s%s was not met\n",
3571 i
->failed_condition
,
3572 i
->failed_condition_negate
? "!" : "",
3573 i
->failed_condition_parameter
);
3576 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3577 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3578 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3580 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3581 ansi_highlight_red(), ansi_normal(),
3582 s2
, s1
? "; " : "", strempty(s1
));
3583 if (i
->failed_assert_trigger
)
3584 printf(" none of the trigger assertions were met\n");
3585 else if (i
->failed_assert
)
3586 printf(" %s=%s%s was not met\n",
3588 i
->failed_assert_negate
? "!" : "",
3589 i
->failed_assert_parameter
);
3593 printf(" Device: %s\n", i
->sysfs_path
);
3595 printf(" Where: %s\n", i
->where
);
3597 printf(" What: %s\n", i
->what
);
3599 STRV_FOREACH(t
, i
->documentation
)
3600 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3602 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3603 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3606 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3608 LIST_FOREACH(exec
, p
, i
->exec
) {
3609 _cleanup_free_
char *argv
= NULL
;
3612 /* Only show exited processes here */
3616 argv
= strv_join(p
->argv
, " ");
3617 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3619 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3621 on
= ansi_highlight_red();
3622 off
= ansi_normal();
3626 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3628 if (p
->code
== CLD_EXITED
) {
3631 printf("status=%i", p
->status
);
3633 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3638 printf("signal=%s", signal_to_string(p
->status
));
3640 printf(")%s\n", off
);
3642 if (i
->main_pid
== p
->pid
&&
3643 i
->start_timestamp
== p
->start_timestamp
&&
3644 i
->exit_timestamp
== p
->start_timestamp
)
3645 /* Let's not show this twice */
3648 if (p
->pid
== i
->control_pid
)
3652 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3653 if (i
->main_pid
> 0) {
3654 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3657 _cleanup_free_
char *comm
= NULL
;
3658 get_process_comm(i
->main_pid
, &comm
);
3660 printf(" (%s)", comm
);
3661 } else if (i
->exit_code
> 0) {
3662 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3664 if (i
->exit_code
== CLD_EXITED
) {
3667 printf("status=%i", i
->exit_status
);
3669 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3674 printf("signal=%s", signal_to_string(i
->exit_status
));
3678 if (i
->control_pid
> 0)
3682 if (i
->control_pid
> 0) {
3683 _cleanup_free_
char *c
= NULL
;
3685 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3687 get_process_comm(i
->control_pid
, &c
);
3696 printf(" Status: \"%s\"\n", i
->status_text
);
3697 if (i
->status_errno
> 0)
3698 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3700 if (i
->tasks_current
!= (uint64_t) -1) {
3701 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3703 if (i
->tasks_max
!= (uint64_t) -1)
3704 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3709 if (i
->memory_current
!= (uint64_t) -1) {
3710 char buf
[FORMAT_BYTES_MAX
];
3712 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3714 if (i
->memory_limit
!= (uint64_t) -1)
3715 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3720 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3721 char buf
[FORMAT_TIMESPAN_MAX
];
3722 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3725 if (i
->control_group
&&
3726 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3727 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3730 printf(" CGroup: %s\n", i
->control_group
);
3732 if (IN_SET(arg_transport
,
3733 BUS_TRANSPORT_LOCAL
,
3734 BUS_TRANSPORT_MACHINE
)) {
3737 static const char prefix
[] = " ";
3740 if (c
> sizeof(prefix
) - 1)
3741 c
-= sizeof(prefix
) - 1;
3745 if (i
->main_pid
> 0)
3746 extra
[k
++] = i
->main_pid
;
3748 if (i
->control_pid
> 0)
3749 extra
[k
++] = i
->control_pid
;
3751 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3755 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3756 show_journal_by_unit(
3761 i
->inactive_exit_timestamp_monotonic
,
3764 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3765 SD_JOURNAL_LOCAL_ONLY
,
3766 arg_scope
== UNIT_FILE_SYSTEM
,
3769 if (i
->need_daemon_reload
)
3770 warn_unit_file_changed(i
->id
);
3773 static void show_unit_help(UnitStatusInfo
*i
) {
3778 if (!i
->documentation
) {
3779 log_info("Documentation for %s not known.", i
->id
);
3783 STRV_FOREACH(p
, i
->documentation
)
3784 if (startswith(*p
, "man:"))
3785 show_man_page(*p
+ 4, false);
3787 log_info("Can't show: %s", *p
);
3790 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3797 switch (contents
[0]) {
3799 case SD_BUS_TYPE_STRING
: {
3802 r
= sd_bus_message_read(m
, "s", &s
);
3804 return bus_log_parse_error(r
);
3807 if (streq(name
, "Id"))
3809 else if (streq(name
, "LoadState"))
3811 else if (streq(name
, "ActiveState"))
3812 i
->active_state
= s
;
3813 else if (streq(name
, "SubState"))
3815 else if (streq(name
, "Description"))
3817 else if (streq(name
, "FragmentPath"))
3818 i
->fragment_path
= s
;
3819 else if (streq(name
, "SourcePath"))
3822 else if (streq(name
, "DefaultControlGroup")) {
3824 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3826 i
->control_group
= e
;
3829 else if (streq(name
, "ControlGroup"))
3830 i
->control_group
= s
;
3831 else if (streq(name
, "StatusText"))
3833 else if (streq(name
, "PIDFile"))
3835 else if (streq(name
, "SysFSPath"))
3837 else if (streq(name
, "Where"))
3839 else if (streq(name
, "What"))
3841 else if (streq(name
, "Following"))
3843 else if (streq(name
, "UnitFileState"))
3844 i
->unit_file_state
= s
;
3845 else if (streq(name
, "UnitFilePreset"))
3846 i
->unit_file_preset
= s
;
3847 else if (streq(name
, "Result"))
3854 case SD_BUS_TYPE_BOOLEAN
: {
3857 r
= sd_bus_message_read(m
, "b", &b
);
3859 return bus_log_parse_error(r
);
3861 if (streq(name
, "Accept"))
3863 else if (streq(name
, "NeedDaemonReload"))
3864 i
->need_daemon_reload
= b
;
3865 else if (streq(name
, "ConditionResult"))
3866 i
->condition_result
= b
;
3867 else if (streq(name
, "AssertResult"))
3868 i
->assert_result
= b
;
3869 else if (streq(name
, "Transient"))
3875 case SD_BUS_TYPE_UINT32
: {
3878 r
= sd_bus_message_read(m
, "u", &u
);
3880 return bus_log_parse_error(r
);
3882 if (streq(name
, "MainPID")) {
3884 i
->main_pid
= (pid_t
) u
;
3887 } else if (streq(name
, "ControlPID"))
3888 i
->control_pid
= (pid_t
) u
;
3889 else if (streq(name
, "ExecMainPID")) {
3891 i
->main_pid
= (pid_t
) u
;
3892 } else if (streq(name
, "NAccepted"))
3894 else if (streq(name
, "NConnections"))
3895 i
->n_connections
= u
;
3900 case SD_BUS_TYPE_INT32
: {
3903 r
= sd_bus_message_read(m
, "i", &j
);
3905 return bus_log_parse_error(r
);
3907 if (streq(name
, "ExecMainCode"))
3908 i
->exit_code
= (int) j
;
3909 else if (streq(name
, "ExecMainStatus"))
3910 i
->exit_status
= (int) j
;
3911 else if (streq(name
, "StatusErrno"))
3912 i
->status_errno
= (int) j
;
3917 case SD_BUS_TYPE_UINT64
: {
3920 r
= sd_bus_message_read(m
, "t", &u
);
3922 return bus_log_parse_error(r
);
3924 if (streq(name
, "ExecMainStartTimestamp"))
3925 i
->start_timestamp
= (usec_t
) u
;
3926 else if (streq(name
, "ExecMainExitTimestamp"))
3927 i
->exit_timestamp
= (usec_t
) u
;
3928 else if (streq(name
, "ActiveEnterTimestamp"))
3929 i
->active_enter_timestamp
= (usec_t
) u
;
3930 else if (streq(name
, "InactiveEnterTimestamp"))
3931 i
->inactive_enter_timestamp
= (usec_t
) u
;
3932 else if (streq(name
, "InactiveExitTimestamp"))
3933 i
->inactive_exit_timestamp
= (usec_t
) u
;
3934 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3935 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3936 else if (streq(name
, "ActiveExitTimestamp"))
3937 i
->active_exit_timestamp
= (usec_t
) u
;
3938 else if (streq(name
, "ConditionTimestamp"))
3939 i
->condition_timestamp
= (usec_t
) u
;
3940 else if (streq(name
, "AssertTimestamp"))
3941 i
->assert_timestamp
= (usec_t
) u
;
3942 else if (streq(name
, "MemoryCurrent"))
3943 i
->memory_current
= u
;
3944 else if (streq(name
, "MemoryLimit"))
3945 i
->memory_limit
= u
;
3946 else if (streq(name
, "TasksCurrent"))
3947 i
->tasks_current
= u
;
3948 else if (streq(name
, "TasksMax"))
3950 else if (streq(name
, "CPUUsageNSec"))
3951 i
->cpu_usage_nsec
= u
;
3956 case SD_BUS_TYPE_ARRAY
:
3958 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3959 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3961 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3963 return bus_log_parse_error(r
);
3965 info
= new0(ExecStatusInfo
, 1);
3969 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3971 info
->name
= strdup(name
);
3975 LIST_PREPEND(exec
, i
->exec
, info
);
3977 info
= new0(ExecStatusInfo
, 1);
3983 return bus_log_parse_error(r
);
3985 r
= sd_bus_message_exit_container(m
);
3987 return bus_log_parse_error(r
);
3991 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3992 const char *type
, *path
;
3994 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3996 return bus_log_parse_error(r
);
3998 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4000 r
= strv_extend(&i
->listen
, type
);
4004 r
= strv_extend(&i
->listen
, path
);
4009 return bus_log_parse_error(r
);
4011 r
= sd_bus_message_exit_container(m
);
4013 return bus_log_parse_error(r
);
4017 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4019 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4021 return bus_log_parse_error(r
);
4023 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4025 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4027 return bus_log_parse_error(r
);
4029 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4030 const char *cond
, *param
;
4031 int trigger
, negate
;
4034 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4036 return bus_log_parse_error(r
);
4038 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4039 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4040 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4041 i
->failed_condition
= cond
;
4042 i
->failed_condition_trigger
= trigger
;
4043 i
->failed_condition_negate
= negate
;
4044 i
->failed_condition_parameter
= param
;
4048 return bus_log_parse_error(r
);
4050 r
= sd_bus_message_exit_container(m
);
4052 return bus_log_parse_error(r
);
4054 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4055 const char *cond
, *param
;
4056 int trigger
, negate
;
4059 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4061 return bus_log_parse_error(r
);
4063 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4064 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4065 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4066 i
->failed_assert
= cond
;
4067 i
->failed_assert_trigger
= trigger
;
4068 i
->failed_assert_negate
= negate
;
4069 i
->failed_assert_parameter
= param
;
4073 return bus_log_parse_error(r
);
4075 r
= sd_bus_message_exit_container(m
);
4077 return bus_log_parse_error(r
);
4084 case SD_BUS_TYPE_STRUCT_BEGIN
:
4086 if (streq(name
, "LoadError")) {
4087 const char *n
, *message
;
4089 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4091 return bus_log_parse_error(r
);
4093 if (!isempty(message
))
4094 i
->load_error
= message
;
4107 r
= sd_bus_message_skip(m
, contents
);
4109 return bus_log_parse_error(r
);
4114 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4120 /* This is a low-level property printer, see
4121 * print_status_info() for the nicer output */
4123 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4124 /* skip what we didn't read */
4125 r
= sd_bus_message_skip(m
, contents
);
4129 switch (contents
[0]) {
4131 case SD_BUS_TYPE_STRUCT_BEGIN
:
4133 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4136 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4138 return bus_log_parse_error(r
);
4141 printf("%s=%"PRIu32
"\n", name
, u
);
4143 printf("%s=\n", name
);
4147 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4150 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4152 return bus_log_parse_error(r
);
4154 if (arg_all
|| !isempty(s
))
4155 printf("%s=%s\n", name
, s
);
4159 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4160 const char *a
= NULL
, *b
= NULL
;
4162 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4164 return bus_log_parse_error(r
);
4166 if (arg_all
|| !isempty(a
) || !isempty(b
))
4167 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4170 } else if (streq_ptr(name
, "SystemCallFilter")) {
4171 _cleanup_strv_free_
char **l
= NULL
;
4174 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4176 return bus_log_parse_error(r
);
4178 r
= sd_bus_message_read(m
, "b", &whitelist
);
4180 return bus_log_parse_error(r
);
4182 r
= sd_bus_message_read_strv(m
, &l
);
4184 return bus_log_parse_error(r
);
4186 r
= sd_bus_message_exit_container(m
);
4188 return bus_log_parse_error(r
);
4190 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4194 fputs(name
, stdout
);
4200 STRV_FOREACH(i
, l
) {
4208 fputc('\n', stdout
);
4216 case SD_BUS_TYPE_ARRAY
:
4218 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4222 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4224 return bus_log_parse_error(r
);
4226 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4227 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4230 return bus_log_parse_error(r
);
4232 r
= sd_bus_message_exit_container(m
);
4234 return bus_log_parse_error(r
);
4238 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4239 const char *type
, *path
;
4241 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4243 return bus_log_parse_error(r
);
4245 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4246 printf("%s=%s\n", type
, path
);
4248 return bus_log_parse_error(r
);
4250 r
= sd_bus_message_exit_container(m
);
4252 return bus_log_parse_error(r
);
4256 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4257 const char *type
, *path
;
4259 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4261 return bus_log_parse_error(r
);
4263 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4264 printf("Listen%s=%s\n", type
, path
);
4266 return bus_log_parse_error(r
);
4268 r
= sd_bus_message_exit_container(m
);
4270 return bus_log_parse_error(r
);
4274 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4276 uint64_t value
, next_elapse
;
4278 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4280 return bus_log_parse_error(r
);
4282 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4283 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4285 printf("%s={ value=%s ; next_elapse=%s }\n",
4287 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4288 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4291 return bus_log_parse_error(r
);
4293 r
= sd_bus_message_exit_container(m
);
4295 return bus_log_parse_error(r
);
4299 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4300 ExecStatusInfo info
= {};
4302 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4304 return bus_log_parse_error(r
);
4306 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4307 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4308 _cleanup_free_
char *tt
;
4310 tt
= strv_join(info
.argv
, " ");
4312 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }\n",
4316 yes_no(info
.ignore
),
4317 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4318 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4320 sigchld_code_to_string(info
.code
),
4322 info
.code
== CLD_EXITED
? "" : "/",
4323 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4326 strv_free(info
.argv
);
4330 r
= sd_bus_message_exit_container(m
);
4332 return bus_log_parse_error(r
);
4336 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4337 const char *path
, *rwm
;
4339 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4341 return bus_log_parse_error(r
);
4343 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4344 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4346 return bus_log_parse_error(r
);
4348 r
= sd_bus_message_exit_container(m
);
4350 return bus_log_parse_error(r
);
4354 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4358 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4360 return bus_log_parse_error(r
);
4362 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4363 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4365 return bus_log_parse_error(r
);
4367 r
= sd_bus_message_exit_container(m
);
4369 return bus_log_parse_error(r
);
4373 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4377 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4379 return bus_log_parse_error(r
);
4381 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4382 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4384 return bus_log_parse_error(r
);
4386 r
= sd_bus_message_exit_container(m
);
4388 return bus_log_parse_error(r
);
4396 r
= bus_print_property(name
, m
, arg_all
);
4398 return bus_log_parse_error(r
);
4401 r
= sd_bus_message_skip(m
, contents
);
4403 return bus_log_parse_error(r
);
4406 printf("%s=[unprintable]\n", name
);
4412 static int show_one(
4416 bool show_properties
,
4420 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4421 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4422 UnitStatusInfo info
= {
4423 .memory_current
= (uint64_t) -1,
4424 .memory_limit
= (uint64_t) -1,
4425 .cpu_usage_nsec
= (uint64_t) -1,
4426 .tasks_current
= (uint64_t) -1,
4427 .tasks_max
= (uint64_t) -1,
4435 log_debug("Showing one %s", path
);
4437 r
= sd_bus_call_method(
4439 "org.freedesktop.systemd1",
4441 "org.freedesktop.DBus.Properties",
4447 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4449 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4451 return bus_log_parse_error(r
);
4458 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4459 const char *name
, *contents
;
4461 r
= sd_bus_message_read(reply
, "s", &name
);
4463 return bus_log_parse_error(r
);
4465 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4467 return bus_log_parse_error(r
);
4469 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4471 return bus_log_parse_error(r
);
4473 if (show_properties
)
4474 r
= print_property(name
, reply
, contents
);
4476 r
= status_property(name
, reply
, &info
, contents
);
4480 r
= sd_bus_message_exit_container(reply
);
4482 return bus_log_parse_error(r
);
4484 r
= sd_bus_message_exit_container(reply
);
4486 return bus_log_parse_error(r
);
4489 return bus_log_parse_error(r
);
4491 r
= sd_bus_message_exit_container(reply
);
4493 return bus_log_parse_error(r
);
4497 if (!show_properties
) {
4498 if (streq(verb
, "help"))
4499 show_unit_help(&info
);
4501 print_status_info(&info
, ellipsized
);
4504 strv_free(info
.documentation
);
4505 strv_free(info
.dropin_paths
);
4506 strv_free(info
.listen
);
4508 if (!streq_ptr(info
.active_state
, "active") &&
4509 !streq_ptr(info
.active_state
, "reloading") &&
4510 streq(verb
, "status")) {
4511 /* According to LSB: "program not running" */
4512 /* 0: program is running or service is OK
4513 * 1: program is dead and /run PID file exists
4514 * 2: program is dead and /run/lock lock file exists
4515 * 3: program is not running
4516 * 4: program or service status is unknown
4518 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4524 while ((p
= info
.exec
)) {
4525 LIST_REMOVE(exec
, info
.exec
, p
);
4526 exec_status_info_free(p
);
4532 static int get_unit_dbus_path_by_pid(
4537 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4538 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4542 r
= sd_bus_call_method(
4544 "org.freedesktop.systemd1",
4545 "/org/freedesktop/systemd1",
4546 "org.freedesktop.systemd1.Manager",
4552 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4554 r
= sd_bus_message_read(reply
, "o", &u
);
4556 return bus_log_parse_error(r
);
4566 static int show_all(
4569 bool show_properties
,
4573 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4574 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4579 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4583 pager_open(arg_no_pager
, false);
4587 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4589 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4590 _cleanup_free_
char *p
= NULL
;
4592 p
= unit_dbus_path_from_name(u
->id
);
4596 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4599 else if (r
> 0 && ret
== 0)
4606 static int show_system_status(sd_bus
*bus
) {
4607 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4608 _cleanup_free_
char *hn
= NULL
;
4609 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4610 const char *on
, *off
;
4613 hn
= gethostname_malloc();
4617 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4619 return log_error_errno(r
, "Failed to read server status: %m");
4621 if (streq_ptr(mi
.state
, "degraded")) {
4622 on
= ansi_highlight_red();
4623 off
= ansi_normal();
4624 } else if (!streq_ptr(mi
.state
, "running")) {
4625 on
= ansi_highlight_yellow();
4626 off
= ansi_normal();
4630 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4632 printf(" State: %s%s%s\n",
4633 on
, strna(mi
.state
), off
);
4635 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4636 printf(" Failed: %u units\n", mi
.n_failed_units
);
4638 printf(" Since: %s; %s\n",
4639 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4640 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4642 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4643 if (IN_SET(arg_transport
,
4644 BUS_TRANSPORT_LOCAL
,
4645 BUS_TRANSPORT_MACHINE
)) {
4646 static const char prefix
[] = " ";
4650 if (c
> sizeof(prefix
) - 1)
4651 c
-= sizeof(prefix
) - 1;
4655 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4661 static int show(int argc
, char *argv
[], void *userdata
) {
4662 bool show_properties
, show_status
, show_help
, new_line
= false;
4663 bool ellipsized
= false;
4669 show_properties
= streq(argv
[0], "show");
4670 show_status
= streq(argv
[0], "status");
4671 show_help
= streq(argv
[0], "help");
4673 if (show_help
&& argc
<= 1) {
4674 log_error("This command expects one or more unit names. Did you mean --help?");
4678 pager_open(arg_no_pager
, false);
4681 /* Increase max number of open files to 16K if we can, we
4682 * might needs this when browsing journal files, which might
4683 * be split up into many files. */
4684 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4686 r
= acquire_bus(BUS_MANAGER
, &bus
);
4690 /* If no argument is specified inspect the manager itself */
4691 if (show_properties
&& argc
<= 1)
4692 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4694 if (show_status
&& argc
<= 1) {
4696 pager_open(arg_no_pager
, false);
4697 show_system_status(bus
);
4701 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4703 _cleanup_free_
char **patterns
= NULL
;
4706 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4707 _cleanup_free_
char *unit
= NULL
;
4710 if (safe_atou32(*name
, &id
) < 0) {
4711 if (strv_push(&patterns
, *name
) < 0)
4715 } else if (show_properties
) {
4716 /* Interpret as job id */
4717 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4721 /* Interpret as PID */
4722 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4729 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4732 else if (r
> 0 && ret
== 0)
4736 if (!strv_isempty(patterns
)) {
4737 _cleanup_strv_free_
char **names
= NULL
;
4739 r
= expand_names(bus
, patterns
, NULL
, &names
);
4741 return log_error_errno(r
, "Failed to expand names: %m");
4743 STRV_FOREACH(name
, names
) {
4744 _cleanup_free_
char *unit
;
4746 unit
= unit_dbus_path_from_name(*name
);
4750 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4753 else if (r
> 0 && ret
== 0)
4759 if (ellipsized
&& !arg_quiet
)
4760 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4765 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4769 assert(user_runtime
);
4772 if (arg_scope
== UNIT_FILE_USER
) {
4773 r
= user_config_home(user_home
);
4775 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4777 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4779 r
= user_runtime_dir(user_runtime
);
4781 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4783 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4786 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4788 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4793 static int cat_file(const char *filename
, bool newline
) {
4794 _cleanup_close_
int fd
;
4796 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4800 printf("%s%s# %s%s\n",
4801 newline
? "\n" : "",
4802 ansi_highlight_blue(),
4807 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4810 static int cat(int argc
, char *argv
[], void *userdata
) {
4811 _cleanup_free_
char *user_home
= NULL
;
4812 _cleanup_free_
char *user_runtime
= NULL
;
4813 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4814 _cleanup_strv_free_
char **names
= NULL
;
4820 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4821 log_error("Cannot remotely cat units.");
4825 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4829 r
= acquire_bus(BUS_MANAGER
, &bus
);
4833 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4835 return log_error_errno(r
, "Failed to expand names: %m");
4837 pager_open(arg_no_pager
, false);
4839 STRV_FOREACH(name
, names
) {
4840 _cleanup_free_
char *fragment_path
= NULL
;
4841 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4844 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4855 if (fragment_path
) {
4856 r
= cat_file(fragment_path
, false);
4858 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4861 STRV_FOREACH(path
, dropin_paths
) {
4862 r
= cat_file(*path
, path
== dropin_paths
);
4864 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4871 static int set_property(int argc
, char *argv
[], void *userdata
) {
4872 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4873 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4874 _cleanup_free_
char *n
= NULL
;
4879 polkit_agent_open_if_enabled();
4881 r
= acquire_bus(BUS_MANAGER
, &bus
);
4885 r
= sd_bus_message_new_method_call(
4888 "org.freedesktop.systemd1",
4889 "/org/freedesktop/systemd1",
4890 "org.freedesktop.systemd1.Manager",
4891 "SetUnitProperties");
4893 return bus_log_create_error(r
);
4895 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4897 return log_error_errno(r
, "Failed to mangle unit name: %m");
4899 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4901 return bus_log_create_error(r
);
4903 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4905 return bus_log_create_error(r
);
4907 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4908 r
= bus_append_unit_property_assignment(m
, *i
);
4913 r
= sd_bus_message_close_container(m
);
4915 return bus_log_create_error(r
);
4917 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4919 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4924 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4925 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4930 polkit_agent_open_if_enabled();
4932 r
= acquire_bus(BUS_MANAGER
, &bus
);
4936 if (arg_action
== ACTION_RELOAD
)
4938 else if (arg_action
== ACTION_REEXEC
)
4939 method
= "Reexecute";
4941 assert(arg_action
== ACTION_SYSTEMCTL
);
4944 streq(argv
[0], "clear-jobs") ||
4945 streq(argv
[0], "cancel") ? "ClearJobs" :
4946 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4947 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4948 streq(argv
[0], "halt") ? "Halt" :
4949 streq(argv
[0], "poweroff") ? "PowerOff" :
4950 streq(argv
[0], "reboot") ? "Reboot" :
4951 streq(argv
[0], "kexec") ? "KExec" :
4952 streq(argv
[0], "exit") ? "Exit" :
4953 /* "daemon-reload" */ "Reload";
4956 r
= sd_bus_call_method(
4958 "org.freedesktop.systemd1",
4959 "/org/freedesktop/systemd1",
4960 "org.freedesktop.systemd1.Manager",
4965 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4966 /* There's always a fallback possible for
4967 * legacy actions. */
4969 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4970 /* On reexecution, we expect a disconnect, not a
4974 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
4976 return r
< 0 ? r
: 0;
4979 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4980 _cleanup_strv_free_
char **names
= NULL
;
4986 return daemon_reload(argc
, argv
, userdata
);
4988 polkit_agent_open_if_enabled();
4990 r
= acquire_bus(BUS_MANAGER
, &bus
);
4994 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4996 return log_error_errno(r
, "Failed to expand names: %m");
4998 STRV_FOREACH(name
, names
) {
4999 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5001 q
= sd_bus_call_method(
5003 "org.freedesktop.systemd1",
5004 "/org/freedesktop/systemd1",
5005 "org.freedesktop.systemd1.Manager",
5011 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5020 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5021 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5022 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5027 pager_open(arg_no_pager
, false);
5029 r
= acquire_bus(BUS_MANAGER
, &bus
);
5033 r
= sd_bus_get_property(
5035 "org.freedesktop.systemd1",
5036 "/org/freedesktop/systemd1",
5037 "org.freedesktop.systemd1.Manager",
5043 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5045 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5047 return bus_log_parse_error(r
);
5049 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5052 return bus_log_parse_error(r
);
5054 r
= sd_bus_message_exit_container(reply
);
5056 return bus_log_parse_error(r
);
5061 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5062 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5063 _cleanup_free_
char *cmdline_init
= NULL
;
5064 const char *root
, *init
;
5068 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5069 log_error("Cannot switch root remotely.");
5073 if (argc
< 2 || argc
> 3) {
5074 log_error("Wrong number of arguments.");
5083 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5084 "init", &cmdline_init
,
5087 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5089 init
= cmdline_init
;
5096 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5098 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5099 root_init_path
= strjoina(root
, "/", init
);
5101 /* If the passed init is actually the same as the
5102 * systemd binary, then let's suppress it. */
5103 if (files_same(root_init_path
, root_systemd_path
) > 0)
5107 r
= acquire_bus(BUS_MANAGER
, &bus
);
5111 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5113 r
= sd_bus_call_method(
5115 "org.freedesktop.systemd1",
5116 "/org/freedesktop/systemd1",
5117 "org.freedesktop.systemd1.Manager",
5123 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5128 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5129 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5130 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5138 polkit_agent_open_if_enabled();
5140 r
= acquire_bus(BUS_MANAGER
, &bus
);
5144 method
= streq(argv
[0], "set-environment")
5146 : "UnsetEnvironment";
5148 r
= sd_bus_message_new_method_call(
5151 "org.freedesktop.systemd1",
5152 "/org/freedesktop/systemd1",
5153 "org.freedesktop.systemd1.Manager",
5156 return bus_log_create_error(r
);
5158 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5160 return bus_log_create_error(r
);
5162 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5164 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5169 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5170 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5171 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5175 polkit_agent_open_if_enabled();
5177 r
= acquire_bus(BUS_MANAGER
, &bus
);
5181 r
= sd_bus_message_new_method_call(
5184 "org.freedesktop.systemd1",
5185 "/org/freedesktop/systemd1",
5186 "org.freedesktop.systemd1.Manager",
5189 return bus_log_create_error(r
);
5192 r
= sd_bus_message_append_strv(m
, environ
);
5196 r
= sd_bus_message_open_container(m
, 'a', "s");
5198 return bus_log_create_error(r
);
5200 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5202 if (!env_name_is_valid(*a
)) {
5203 log_error("Not a valid environment variable name: %s", *a
);
5207 STRV_FOREACH(b
, environ
) {
5210 eq
= startswith(*b
, *a
);
5211 if (eq
&& *eq
== '=') {
5213 r
= sd_bus_message_append(m
, "s", *b
);
5215 return bus_log_create_error(r
);
5222 r
= sd_bus_message_close_container(m
);
5225 return bus_log_create_error(r
);
5227 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5229 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5234 static int enable_sysv_units(const char *verb
, char **args
) {
5237 #if defined(HAVE_SYSV_COMPAT)
5239 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5241 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5244 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5247 if (!STR_IN_SET(verb
,
5253 /* Processes all SysV units, and reshuffles the array so that
5254 * afterwards only the native units remain */
5256 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5263 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5264 bool found_native
= false, found_sysv
;
5266 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5274 if (!endswith(name
, ".service"))
5277 if (path_is_absolute(name
))
5280 STRV_FOREACH(k
, paths
.unit_path
) {
5281 _cleanup_free_
char *path
= NULL
;
5283 path
= path_join(arg_root
, *k
, name
);
5287 found_native
= access(path
, F_OK
) >= 0;
5292 /* If we have both a native unit and a SysV script,
5293 * enable/disable them both (below); for is-enabled, prefer the
5295 if (found_native
&& streq(verb
, "is-enabled"))
5298 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5302 p
[strlen(p
) - strlen(".service")] = 0;
5303 found_sysv
= access(p
, F_OK
) >= 0;
5308 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5310 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5312 if (!isempty(arg_root
))
5313 argv
[c
++] = q
= strappend("--root=", arg_root
);
5316 argv
[c
++] = basename(p
);
5319 l
= strv_join((char**)argv
, " ");
5323 log_info("Executing %s", l
);
5327 return log_error_errno(errno
, "Failed to fork: %m");
5328 else if (pid
== 0) {
5331 (void) reset_all_signal_handlers();
5332 (void) reset_signal_mask();
5334 execv(argv
[0], (char**) argv
);
5335 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5336 _exit(EXIT_FAILURE
);
5339 j
= wait_for_terminate(pid
, &status
);
5341 log_error_errno(j
, "Failed to wait for child: %m");
5345 if (status
.si_code
== CLD_EXITED
) {
5346 if (streq(verb
, "is-enabled")) {
5347 if (status
.si_status
== 0) {
5356 } else if (status
.si_status
!= 0)
5364 /* Remove this entry, so that we don't try enabling it as native unit */
5367 assert(args
[f
] == name
);
5368 strv_remove(args
, name
);
5375 static int mangle_names(char **original_names
, char ***mangled_names
) {
5376 char **i
, **l
, **name
;
5379 l
= i
= new(char*, strv_length(original_names
) + 1);
5383 STRV_FOREACH(name
, original_names
) {
5385 /* When enabling units qualified path names are OK,
5386 * too, hence allow them explicitly. */
5388 if (is_path(*name
)) {
5395 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5398 return log_error_errno(r
, "Failed to mangle unit name: %m");
5411 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5412 _cleanup_strv_free_
char **names
= NULL
;
5413 const char *verb
= argv
[0];
5414 UnitFileChange
*changes
= NULL
;
5415 unsigned n_changes
= 0;
5416 int carries_install_info
= -1;
5422 r
= mangle_names(strv_skip(argv
, 1), &names
);
5426 r
= enable_sysv_units(verb
, names
);
5430 /* If the operation was fully executed by the SysV compat,
5431 * let's finish early */
5432 if (strv_isempty(names
))
5435 if (install_client_side()) {
5436 if (streq(verb
, "enable")) {
5437 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5438 carries_install_info
= r
;
5439 } else if (streq(verb
, "disable"))
5440 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5441 else if (streq(verb
, "reenable")) {
5442 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5443 carries_install_info
= r
;
5444 } else if (streq(verb
, "link"))
5445 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5446 else if (streq(verb
, "preset")) {
5447 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5448 carries_install_info
= r
;
5449 } else if (streq(verb
, "mask"))
5450 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5451 else if (streq(verb
, "unmask"))
5452 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5454 assert_not_reached("Unknown verb");
5456 if (r
== -ESHUTDOWN
)
5457 return log_error_errno(r
, "Unit file is masked.");
5459 return log_error_errno(r
, "Operation failed: %m");
5462 dump_unit_file_changes(changes
, n_changes
);
5466 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5467 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5468 int expect_carries_install_info
= false;
5469 bool send_force
= true, send_preset_mode
= false;
5473 polkit_agent_open_if_enabled();
5475 r
= acquire_bus(BUS_MANAGER
, &bus
);
5479 if (streq(verb
, "enable")) {
5480 method
= "EnableUnitFiles";
5481 expect_carries_install_info
= true;
5482 } else if (streq(verb
, "disable")) {
5483 method
= "DisableUnitFiles";
5485 } else if (streq(verb
, "reenable")) {
5486 method
= "ReenableUnitFiles";
5487 expect_carries_install_info
= true;
5488 } else if (streq(verb
, "link"))
5489 method
= "LinkUnitFiles";
5490 else if (streq(verb
, "preset")) {
5492 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5493 method
= "PresetUnitFilesWithMode";
5494 send_preset_mode
= true;
5496 method
= "PresetUnitFiles";
5498 expect_carries_install_info
= true;
5499 } else if (streq(verb
, "mask"))
5500 method
= "MaskUnitFiles";
5501 else if (streq(verb
, "unmask")) {
5502 method
= "UnmaskUnitFiles";
5505 assert_not_reached("Unknown verb");
5507 r
= sd_bus_message_new_method_call(
5510 "org.freedesktop.systemd1",
5511 "/org/freedesktop/systemd1",
5512 "org.freedesktop.systemd1.Manager",
5515 return bus_log_create_error(r
);
5517 r
= sd_bus_message_append_strv(m
, names
);
5519 return bus_log_create_error(r
);
5521 if (send_preset_mode
) {
5522 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5524 return bus_log_create_error(r
);
5527 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5529 return bus_log_create_error(r
);
5532 r
= sd_bus_message_append(m
, "b", arg_force
);
5534 return bus_log_create_error(r
);
5537 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5539 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5541 if (expect_carries_install_info
) {
5542 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5544 return bus_log_parse_error(r
);
5547 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5551 /* Try to reload if enabled */
5553 r
= daemon_reload(argc
, argv
, userdata
);
5558 if (carries_install_info
== 0)
5559 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5560 "using systemctl.\n"
5561 "Possible reasons for having this kind of units are:\n"
5562 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5563 " .wants/ or .requires/ directory.\n"
5564 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5565 " a requirement dependency on it.\n"
5566 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5567 " D-Bus, udev, scripted systemctl call, ...).\n");
5569 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5570 char *new_args
[n_changes
+ 2];
5574 r
= acquire_bus(BUS_MANAGER
, &bus
);
5578 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5579 for (i
= 0; i
< n_changes
; i
++)
5580 new_args
[i
+ 1] = basename(changes
[i
].path
);
5581 new_args
[i
+ 1] = NULL
;
5583 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5587 unit_file_changes_free(changes
, n_changes
);
5592 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5593 _cleanup_strv_free_
char **names
= NULL
;
5594 _cleanup_free_
char *target
= NULL
;
5595 const char *verb
= argv
[0];
5602 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5604 return log_error_errno(r
, "Failed to mangle unit name: %m");
5606 r
= mangle_names(strv_skip(argv
, 2), &names
);
5610 if (streq(verb
, "add-wants"))
5612 else if (streq(verb
, "add-requires"))
5613 dep
= UNIT_REQUIRES
;
5615 assert_not_reached("Unknown verb");
5617 if (install_client_side()) {
5618 UnitFileChange
*changes
= NULL
;
5619 unsigned n_changes
= 0;
5621 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5622 if (r
== -ESHUTDOWN
)
5623 return log_error_errno(r
, "Unit file is masked.");
5625 return log_error_errno(r
, "Can't add dependency: %m");
5628 dump_unit_file_changes(changes
, n_changes
);
5630 unit_file_changes_free(changes
, n_changes
);
5633 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5634 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5637 polkit_agent_open_if_enabled();
5639 r
= acquire_bus(BUS_MANAGER
, &bus
);
5643 r
= sd_bus_message_new_method_call(
5646 "org.freedesktop.systemd1",
5647 "/org/freedesktop/systemd1",
5648 "org.freedesktop.systemd1.Manager",
5649 "AddDependencyUnitFiles");
5651 return bus_log_create_error(r
);
5653 r
= sd_bus_message_append_strv(m
, names
);
5655 return bus_log_create_error(r
);
5657 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5659 return bus_log_create_error(r
);
5661 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5663 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5665 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5670 r
= daemon_reload(argc
, argv
, userdata
);
5678 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5679 UnitFileChange
*changes
= NULL
;
5680 unsigned n_changes
= 0;
5683 if (install_client_side()) {
5685 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5687 log_error_errno(r
, "Operation failed: %m");
5692 dump_unit_file_changes(changes
, n_changes
);
5697 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5698 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5701 polkit_agent_open_if_enabled();
5703 r
= acquire_bus(BUS_MANAGER
, &bus
);
5707 r
= sd_bus_call_method(
5709 "org.freedesktop.systemd1",
5710 "/org/freedesktop/systemd1",
5711 "org.freedesktop.systemd1.Manager",
5712 "PresetAllUnitFiles",
5716 unit_file_preset_mode_to_string(arg_preset_mode
),
5720 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5722 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5727 r
= daemon_reload(argc
, argv
, userdata
);
5733 unit_file_changes_free(changes
, n_changes
);
5738 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5740 _cleanup_strv_free_
char **names
= NULL
;
5745 r
= mangle_names(strv_skip(argv
, 1), &names
);
5749 r
= enable_sysv_units(argv
[0], names
);
5755 if (install_client_side()) {
5757 STRV_FOREACH(name
, names
) {
5758 UnitFileState state
;
5760 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5762 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5766 UNIT_FILE_ENABLED_RUNTIME
,
5768 UNIT_FILE_INDIRECT
))
5772 puts(unit_file_state_to_string(state
));
5776 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5779 r
= acquire_bus(BUS_MANAGER
, &bus
);
5783 STRV_FOREACH(name
, names
) {
5784 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5787 r
= sd_bus_call_method(
5789 "org.freedesktop.systemd1",
5790 "/org/freedesktop/systemd1",
5791 "org.freedesktop.systemd1.Manager",
5797 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5799 r
= sd_bus_message_read(reply
, "s", &s
);
5801 return bus_log_parse_error(r
);
5803 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5814 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5815 _cleanup_free_
char *state
= NULL
;
5819 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5822 return EXIT_FAILURE
;
5825 r
= acquire_bus(BUS_MANAGER
, &bus
);
5829 r
= sd_bus_get_property_string(
5831 "org.freedesktop.systemd1",
5832 "/org/freedesktop/systemd1",
5833 "org.freedesktop.systemd1.Manager",
5846 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5849 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5850 _cleanup_free_
char *t
= NULL
;
5854 assert(original_path
);
5857 r
= tempfn_random(new_path
, NULL
, &t
);
5859 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5861 r
= mkdir_parents(new_path
, 0755);
5863 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5865 r
= copy_file(original_path
, t
, 0, 0644, 0);
5870 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5873 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5881 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5882 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5887 switch (arg_scope
) {
5888 case UNIT_FILE_SYSTEM
:
5889 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5891 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5893 case UNIT_FILE_GLOBAL
:
5894 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5896 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5898 case UNIT_FILE_USER
:
5900 assert(user_runtime
);
5902 path
= path_join(arg_root
, user_home
, name
);
5904 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5907 run
= path_join(arg_root
, user_runtime
, name
);
5911 assert_not_reached("Invalid scope");
5913 if (!path
|| (arg_runtime
&& !run
))
5917 if (access(path
, F_OK
) >= 0) {
5918 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5922 if (path2
&& access(path2
, F_OK
) >= 0) {
5923 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5937 static int unit_file_create_dropin(const char *unit_name
, const char *user_home
, const char *user_runtime
, char **ret_new_path
, char **ret_tmp_path
) {
5938 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5942 assert(ret_new_path
);
5943 assert(ret_tmp_path
);
5945 ending
= strjoina(unit_name
, ".d/override.conf");
5946 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5950 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5956 *ret_new_path
= tmp_new_path
;
5957 *ret_tmp_path
= tmp_tmp_path
;
5962 static int unit_file_create_copy(
5963 const char *unit_name
,
5964 const char *fragment_path
,
5965 const char *user_home
,
5966 const char *user_runtime
,
5967 char **ret_new_path
,
5968 char **ret_tmp_path
) {
5970 char *tmp_new_path
, *tmp_tmp_path
;
5973 assert(fragment_path
);
5975 assert(ret_new_path
);
5976 assert(ret_tmp_path
);
5978 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5982 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5985 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5990 if (response
!= 'y') {
5991 log_warning("%s ignored", unit_name
);
5997 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5999 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6004 *ret_new_path
= tmp_new_path
;
6005 *ret_tmp_path
= tmp_tmp_path
;
6010 static int run_editor(char **paths
) {
6018 return log_error_errno(errno
, "Failed to fork: %m");
6022 char *editor
, **editor_args
= NULL
;
6023 char **tmp_path
, **original_path
, *p
;
6024 unsigned n_editor_args
= 0, i
= 1;
6027 (void) reset_all_signal_handlers();
6028 (void) reset_signal_mask();
6030 argc
= strv_length(paths
)/2 + 1;
6032 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6033 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6034 * we try to execute well known editors
6036 editor
= getenv("SYSTEMD_EDITOR");
6038 editor
= getenv("EDITOR");
6040 editor
= getenv("VISUAL");
6042 if (!isempty(editor
)) {
6043 editor_args
= strv_split(editor
, WHITESPACE
);
6046 _exit(EXIT_FAILURE
);
6048 n_editor_args
= strv_length(editor_args
);
6049 argc
+= n_editor_args
- 1;
6051 args
= newa(const char*, argc
+ 1);
6053 if (n_editor_args
> 0) {
6054 args
[0] = editor_args
[0];
6055 for (; i
< n_editor_args
; i
++)
6056 args
[i
] = editor_args
[i
];
6059 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6060 args
[i
] = *tmp_path
;
6065 if (n_editor_args
> 0)
6066 execvp(args
[0], (char* const*) args
);
6068 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6070 execvp(p
, (char* const*) args
);
6071 /* We do not fail if the editor doesn't exist
6072 * because we want to try each one of them before
6075 if (errno
!= ENOENT
) {
6076 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6077 _exit(EXIT_FAILURE
);
6081 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6082 _exit(EXIT_FAILURE
);
6085 r
= wait_for_terminate_and_warn("editor", pid
, true);
6087 return log_error_errno(r
, "Failed to wait for child: %m");
6092 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6093 _cleanup_free_
char *user_home
= NULL
;
6094 _cleanup_free_
char *user_runtime
= NULL
;
6095 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6102 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6106 STRV_FOREACH(name
, names
) {
6107 _cleanup_free_
char *path
= NULL
;
6108 char *new_path
, *tmp_path
;
6110 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6116 // FIXME: support units with path==NULL (no FragmentPath)
6117 log_error("No fragment exists for %s.", *name
);
6122 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6124 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6128 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6136 static int edit(int argc
, char *argv
[], void *userdata
) {
6137 _cleanup_strv_free_
char **names
= NULL
;
6138 _cleanup_strv_free_
char **paths
= NULL
;
6139 char **original
, **tmp
;
6144 log_error("Cannot edit units if not on a tty.");
6148 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6149 log_error("Cannot edit units remotely.");
6153 r
= acquire_bus(BUS_MANAGER
, &bus
);
6157 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6159 return log_error_errno(r
, "Failed to expand names: %m");
6161 r
= find_paths_to_edit(bus
, names
, &paths
);
6165 if (strv_isempty(paths
))
6168 r
= run_editor(paths
);
6172 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6173 /* If the temporary file is empty we ignore it. It's
6174 * useful if the user wants to cancel its modification
6176 if (null_or_empty_path(*tmp
)) {
6177 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6181 r
= rename(*tmp
, *original
);
6183 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6190 if (!arg_no_reload
&& !install_client_side())
6191 r
= daemon_reload(argc
, argv
, userdata
);
6194 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6195 (void) unlink(*tmp
);
6197 /* Removing empty dropin dirs */
6199 _cleanup_free_
char *dir
;
6201 dir
= dirname_malloc(*original
);
6205 /* no need to check if the dir is empty, rmdir
6206 * does nothing if it is not the case.
6215 static void systemctl_help(void) {
6217 pager_open(arg_no_pager
, false);
6219 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6220 "Query or send control commands to the systemd manager.\n\n"
6221 " -h --help Show this help\n"
6222 " --version Show package version\n"
6223 " --system Connect to system manager\n"
6224 " --user Connect to user service manager\n"
6225 " -H --host=[USER@]HOST\n"
6226 " Operate on remote host\n"
6227 " -M --machine=CONTAINER\n"
6228 " Operate on local container\n"
6229 " -t --type=TYPE List units of a particular type\n"
6230 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6231 " -p --property=NAME Show only properties by this name\n"
6232 " -a --all Show all loaded units/properties, including dead/empty\n"
6233 " ones. To list all units installed on the system, use\n"
6234 " the 'list-unit-files' command instead.\n"
6235 " -l --full Don't ellipsize unit names on output\n"
6236 " -r --recursive Show unit list of host and local containers\n"
6237 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6238 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6239 " queueing a new job\n"
6240 " --show-types When showing sockets, explicitly show their type\n"
6241 " -i --ignore-inhibitors\n"
6242 " When shutting down or sleeping, ignore inhibitors\n"
6243 " --kill-who=WHO Who to send signal to\n"
6244 " -s --signal=SIGNAL Which signal to send\n"
6245 " --now Start or stop unit in addition to enabling or disabling it\n"
6246 " -q --quiet Suppress output\n"
6247 " --no-block Do not wait until operation finished\n"
6248 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6249 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6250 " --no-legend Do not print a legend (column headers and hints)\n"
6251 " --no-pager Do not pipe output into a pager\n"
6252 " --no-ask-password\n"
6253 " Do not ask for system passwords\n"
6254 " --global Enable/disable unit files globally\n"
6255 " --runtime Enable unit files only temporarily until next reboot\n"
6256 " -f --force When enabling unit files, override existing symlinks\n"
6257 " When shutting down, execute action immediately\n"
6258 " --preset-mode= Apply only enable, only disable, or all presets\n"
6259 " --root=PATH Enable unit files in the specified root directory\n"
6260 " -n --lines=INTEGER Number of journal entries to show\n"
6261 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6262 " short-precise, short-monotonic, verbose,\n"
6263 " export, json, json-pretty, json-sse, cat)\n"
6264 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6265 " --plain Print unit dependencies as a list instead of a tree\n\n"
6267 " list-units [PATTERN...] List loaded units\n"
6268 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6269 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6270 " start NAME... Start (activate) one or more units\n"
6271 " stop NAME... Stop (deactivate) one or more units\n"
6272 " reload NAME... Reload one or more units\n"
6273 " restart NAME... Start or restart one or more units\n"
6274 " try-restart NAME... Restart one or more units if active\n"
6275 " reload-or-restart NAME... Reload one or more units if possible,\n"
6276 " otherwise start or restart\n"
6277 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6278 " if supported, otherwise restart\n"
6279 " isolate NAME Start one unit and stop all others\n"
6280 " kill NAME... Send signal to processes of a unit\n"
6281 " is-active PATTERN... Check whether units are active\n"
6282 " is-failed PATTERN... Check whether units are failed\n"
6283 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6284 " show [PATTERN...|JOB...] Show properties of one or more\n"
6285 " units/jobs or the manager\n"
6286 " cat PATTERN... Show files and drop-ins of one or more units\n"
6287 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6288 " help PATTERN...|PID... Show manual for one or more units\n"
6289 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6291 " list-dependencies [NAME] Recursively show units which are required\n"
6292 " or wanted by this unit or by which this\n"
6293 " unit is required or wanted\n\n"
6294 "Unit File Commands:\n"
6295 " list-unit-files [PATTERN...] List installed unit files\n"
6296 " enable NAME... Enable one or more unit files\n"
6297 " disable NAME... Disable one or more unit files\n"
6298 " reenable NAME... Reenable one or more unit files\n"
6299 " preset NAME... Enable/disable one or more unit files\n"
6300 " based on preset configuration\n"
6301 " preset-all Enable/disable all unit files based on\n"
6302 " preset configuration\n"
6303 " is-enabled NAME... Check whether unit files are enabled\n"
6304 " mask NAME... Mask one or more units\n"
6305 " unmask NAME... Unmask one or more units\n"
6306 " link PATH... Link one or more units files into\n"
6307 " the search path\n"
6308 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6309 " on specified one or more units\n"
6310 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6311 " on specified one or more units\n"
6312 " edit NAME... Edit one or more unit files\n"
6313 " get-default Get the name of the default target\n"
6314 " set-default NAME Set the default target\n\n"
6315 "Machine Commands:\n"
6316 " list-machines [PATTERN...] List local containers and host\n\n"
6318 " list-jobs [PATTERN...] List jobs\n"
6319 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6320 "Environment Commands:\n"
6321 " show-environment Dump environment\n"
6322 " set-environment NAME=VALUE... Set one or more environment variables\n"
6323 " unset-environment NAME... Unset one or more environment variables\n"
6324 " import-environment [NAME...] Import all or some environment variables\n\n"
6325 "Manager Lifecycle Commands:\n"
6326 " daemon-reload Reload systemd manager configuration\n"
6327 " daemon-reexec Reexecute systemd manager\n\n"
6328 "System Commands:\n"
6329 " is-system-running Check whether system is fully running\n"
6330 " default Enter system default mode\n"
6331 " rescue Enter system rescue mode\n"
6332 " emergency Enter system emergency mode\n"
6333 " halt Shut down and halt the system\n"
6334 " poweroff Shut down and power-off the system\n"
6335 " reboot [ARG] Shut down and reboot the system\n"
6336 " kexec Shut down and reboot the system with kexec\n"
6337 " exit [EXIT_CODE] Request user instance or container exit\n"
6338 " switch-root ROOT [INIT] Change to a different root file system\n"
6339 " suspend Suspend the system\n"
6340 " hibernate Hibernate the system\n"
6341 " hybrid-sleep Hibernate and suspend the system\n",
6342 program_invocation_short_name
);
6345 static void halt_help(void) {
6346 printf("%s [OPTIONS...]%s\n\n"
6347 "%s the system.\n\n"
6348 " --help Show this help\n"
6349 " --halt Halt the machine\n"
6350 " -p --poweroff Switch off the machine\n"
6351 " --reboot Reboot the machine\n"
6352 " -f --force Force immediate halt/power-off/reboot\n"
6353 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6354 " -d --no-wtmp Don't write wtmp record\n"
6355 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6356 program_invocation_short_name
,
6357 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6358 arg_action
== ACTION_REBOOT
? "Reboot" :
6359 arg_action
== ACTION_POWEROFF
? "Power off" :
6363 static void shutdown_help(void) {
6364 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6365 "Shut down the system.\n\n"
6366 " --help Show this help\n"
6367 " -H --halt Halt the machine\n"
6368 " -P --poweroff Power-off the machine\n"
6369 " -r --reboot Reboot the machine\n"
6370 " -h Equivalent to --poweroff, overridden by --halt\n"
6371 " -k Don't halt/power-off/reboot, just send warnings\n"
6372 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6373 " -c Cancel a pending shutdown\n",
6374 program_invocation_short_name
);
6377 static void telinit_help(void) {
6378 printf("%s [OPTIONS...] {COMMAND}\n\n"
6379 "Send control commands to the init daemon.\n\n"
6380 " --help Show this help\n"
6381 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6383 " 0 Power-off the machine\n"
6384 " 6 Reboot the machine\n"
6385 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6386 " 1, s, S Enter rescue mode\n"
6387 " q, Q Reload init daemon configuration\n"
6388 " u, U Reexecute init daemon\n",
6389 program_invocation_short_name
);
6392 static void runlevel_help(void) {
6393 printf("%s [OPTIONS...]\n\n"
6394 "Prints the previous and current runlevel of the init system.\n\n"
6395 " --help Show this help\n",
6396 program_invocation_short_name
);
6399 static void help_types(void) {
6403 puts("Available unit types:");
6404 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6405 puts(unit_type_to_string(i
));
6408 static void help_states(void) {
6412 puts("Available unit load states:");
6413 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6414 puts(unit_load_state_to_string(i
));
6417 puts("\nAvailable unit active states:");
6418 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6419 puts(unit_active_state_to_string(i
));
6422 puts("\nAvailable automount unit substates:");
6423 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6424 puts(automount_state_to_string(i
));
6427 puts("\nAvailable busname unit substates:");
6428 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6429 puts(busname_state_to_string(i
));
6432 puts("\nAvailable device unit substates:");
6433 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6434 puts(device_state_to_string(i
));
6437 puts("\nAvailable mount unit substates:");
6438 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6439 puts(mount_state_to_string(i
));
6442 puts("\nAvailable path unit substates:");
6443 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6444 puts(path_state_to_string(i
));
6447 puts("\nAvailable scope unit substates:");
6448 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6449 puts(scope_state_to_string(i
));
6452 puts("\nAvailable service unit substates:");
6453 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6454 puts(service_state_to_string(i
));
6457 puts("\nAvailable slice unit substates:");
6458 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6459 puts(slice_state_to_string(i
));
6462 puts("\nAvailable socket unit substates:");
6463 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6464 puts(socket_state_to_string(i
));
6467 puts("\nAvailable swap unit substates:");
6468 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6469 puts(swap_state_to_string(i
));
6472 puts("\nAvailable target unit substates:");
6473 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6474 puts(target_state_to_string(i
));
6477 puts("\nAvailable timer unit substates:");
6478 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6479 puts(timer_state_to_string(i
));
6482 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6491 ARG_IGNORE_DEPENDENCIES
,
6503 ARG_NO_ASK_PASSWORD
,
6516 static const struct option options
[] = {
6517 { "help", no_argument
, NULL
, 'h' },
6518 { "version", no_argument
, NULL
, ARG_VERSION
},
6519 { "type", required_argument
, NULL
, 't' },
6520 { "property", required_argument
, NULL
, 'p' },
6521 { "all", no_argument
, NULL
, 'a' },
6522 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6523 { "after", no_argument
, NULL
, ARG_AFTER
},
6524 { "before", no_argument
, NULL
, ARG_BEFORE
},
6525 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6526 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6527 { "full", no_argument
, NULL
, 'l' },
6528 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6529 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6530 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6531 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6532 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6533 { "user", no_argument
, NULL
, ARG_USER
},
6534 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6535 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6536 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6537 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6538 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6539 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6540 { "quiet", no_argument
, NULL
, 'q' },
6541 { "root", required_argument
, NULL
, ARG_ROOT
},
6542 { "force", no_argument
, NULL
, ARG_FORCE
},
6543 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6544 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6545 { "signal", required_argument
, NULL
, 's' },
6546 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6547 { "host", required_argument
, NULL
, 'H' },
6548 { "machine", required_argument
, NULL
, 'M' },
6549 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6550 { "lines", required_argument
, NULL
, 'n' },
6551 { "output", required_argument
, NULL
, 'o' },
6552 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6553 { "state", required_argument
, NULL
, ARG_STATE
},
6554 { "recursive", no_argument
, NULL
, 'r' },
6555 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6556 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6557 { "now", no_argument
, NULL
, ARG_NOW
},
6558 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6568 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6569 arg_ask_password
= true;
6571 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6583 if (isempty(optarg
)) {
6584 log_error("--type requires arguments.");
6590 _cleanup_free_
char *type
= NULL
;
6592 r
= extract_first_word(&p
, &type
, ",", 0);
6594 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6599 if (streq(type
, "help")) {
6604 if (unit_type_from_string(type
) >= 0) {
6605 if (strv_push(&arg_types
, type
) < 0)
6611 /* It's much nicer to use --state= for
6612 * load states, but let's support this
6613 * in --types= too for compatibility
6614 * with old versions */
6615 if (unit_load_state_from_string(type
) >= 0) {
6616 if (strv_push(&arg_states
, type
) < 0)
6622 log_error("Unknown unit type or load state '%s'.", type
);
6623 log_info("Use -t help to see a list of allowed values.");
6631 /* Make sure that if the empty property list
6632 was specified, we won't show any properties. */
6633 if (isempty(optarg
) && !arg_properties
) {
6634 arg_properties
= new0(char*, 1);
6635 if (!arg_properties
)
6640 _cleanup_free_
char *prop
= NULL
;
6642 r
= extract_first_word(&p
, &prop
, ",", 0);
6644 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6649 if (strv_push(&arg_properties
, prop
) < 0)
6656 /* If the user asked for a particular
6657 * property, show it to him, even if it is
6669 arg_dependency
= DEPENDENCY_REVERSE
;
6673 arg_dependency
= DEPENDENCY_AFTER
;
6677 arg_dependency
= DEPENDENCY_BEFORE
;
6680 case ARG_SHOW_TYPES
:
6681 arg_show_types
= true;
6685 arg_job_mode
= optarg
;
6689 arg_job_mode
= "fail";
6692 case ARG_IRREVERSIBLE
:
6693 arg_job_mode
= "replace-irreversibly";
6696 case ARG_IGNORE_DEPENDENCIES
:
6697 arg_job_mode
= "ignore-dependencies";
6701 arg_scope
= UNIT_FILE_USER
;
6705 arg_scope
= UNIT_FILE_SYSTEM
;
6709 arg_scope
= UNIT_FILE_GLOBAL
;
6713 arg_no_block
= true;
6717 arg_no_legend
= true;
6721 arg_no_pager
= true;
6729 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6739 if (strv_extend(&arg_states
, "failed") < 0)
6757 arg_no_reload
= true;
6761 arg_kill_who
= optarg
;
6765 arg_signal
= signal_from_string_try_harder(optarg
);
6766 if (arg_signal
< 0) {
6767 log_error("Failed to parse signal string %s.", optarg
);
6772 case ARG_NO_ASK_PASSWORD
:
6773 arg_ask_password
= false;
6777 arg_transport
= BUS_TRANSPORT_REMOTE
;
6782 arg_transport
= BUS_TRANSPORT_MACHINE
;
6791 if (safe_atou(optarg
, &arg_lines
) < 0) {
6792 log_error("Failed to parse lines '%s'", optarg
);
6798 arg_output
= output_mode_from_string(optarg
);
6799 if (arg_output
< 0) {
6800 log_error("Unknown output '%s'.", optarg
);
6806 arg_ignore_inhibitors
= true;
6813 case ARG_FIRMWARE_SETUP
:
6814 arg_firmware_setup
= true;
6818 if (isempty(optarg
)) {
6819 log_error("--signal requires arguments.");
6825 _cleanup_free_
char *s
= NULL
;
6827 r
= extract_first_word(&p
, &s
, ",", 0);
6829 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6834 if (streq(s
, "help")) {
6839 if (strv_push(&arg_states
, s
) < 0)
6848 if (geteuid() != 0) {
6849 log_error("--recursive requires root privileges.");
6853 arg_recursive
= true;
6856 case ARG_PRESET_MODE
:
6858 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6859 if (arg_preset_mode
< 0) {
6860 log_error("Failed to parse preset mode: %s.", optarg
);
6871 if (strv_extend(&arg_wall
, optarg
) < 0)
6879 assert_not_reached("Unhandled option");
6882 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6883 log_error("Cannot access user instance remotely.");
6890 static int halt_parse_argv(int argc
, char *argv
[]) {
6899 static const struct option options
[] = {
6900 { "help", no_argument
, NULL
, ARG_HELP
},
6901 { "halt", no_argument
, NULL
, ARG_HALT
},
6902 { "poweroff", no_argument
, NULL
, 'p' },
6903 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6904 { "force", no_argument
, NULL
, 'f' },
6905 { "wtmp-only", no_argument
, NULL
, 'w' },
6906 { "no-wtmp", no_argument
, NULL
, 'd' },
6907 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6916 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6917 if (runlevel
== '0' || runlevel
== '6')
6920 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6928 arg_action
= ACTION_HALT
;
6932 if (arg_action
!= ACTION_REBOOT
)
6933 arg_action
= ACTION_POWEROFF
;
6937 arg_action
= ACTION_REBOOT
;
6959 /* Compatibility nops */
6966 assert_not_reached("Unhandled option");
6969 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6970 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6973 } else if (optind
< argc
) {
6974 log_error("Too many arguments.");
6981 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
6985 if (streq(t
, "now"))
6987 else if (!strchr(t
, ':')) {
6990 if (safe_atou64(t
, &u
) < 0)
6993 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7002 hour
= strtol(t
, &e
, 10);
7003 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7006 minute
= strtol(e
+1, &e
, 10);
7007 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7010 n
= now(CLOCK_REALTIME
);
7011 s
= (time_t) (n
/ USEC_PER_SEC
);
7013 assert_se(localtime_r(&s
, &tm
));
7015 tm
.tm_hour
= (int) hour
;
7016 tm
.tm_min
= (int) minute
;
7019 assert_se(s
= mktime(&tm
));
7021 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7024 *_u
+= USEC_PER_DAY
;
7030 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7037 static const struct option options
[] = {
7038 { "help", no_argument
, NULL
, ARG_HELP
},
7039 { "halt", no_argument
, NULL
, 'H' },
7040 { "poweroff", no_argument
, NULL
, 'P' },
7041 { "reboot", no_argument
, NULL
, 'r' },
7042 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7043 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7053 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7061 arg_action
= ACTION_HALT
;
7065 arg_action
= ACTION_POWEROFF
;
7070 arg_action
= ACTION_KEXEC
;
7072 arg_action
= ACTION_REBOOT
;
7076 arg_action
= ACTION_KEXEC
;
7080 if (arg_action
!= ACTION_HALT
)
7081 arg_action
= ACTION_POWEROFF
;
7096 /* Compatibility nops */
7100 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7107 assert_not_reached("Unhandled option");
7110 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7111 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7113 log_error("Failed to parse time specification: %s", argv
[optind
]);
7117 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7119 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7120 /* No time argument for shutdown cancel */
7121 wall
= argv
+ optind
;
7122 else if (argc
> optind
+ 1)
7123 /* We skip the time argument */
7124 wall
= argv
+ optind
+ 1;
7127 arg_wall
= strv_copy(wall
);
7137 static int telinit_parse_argv(int argc
, char *argv
[]) {
7144 static const struct option options
[] = {
7145 { "help", no_argument
, NULL
, ARG_HELP
},
7146 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7150 static const struct {
7154 { '0', ACTION_POWEROFF
},
7155 { '6', ACTION_REBOOT
},
7156 { '1', ACTION_RESCUE
},
7157 { '2', ACTION_RUNLEVEL2
},
7158 { '3', ACTION_RUNLEVEL3
},
7159 { '4', ACTION_RUNLEVEL4
},
7160 { '5', ACTION_RUNLEVEL5
},
7161 { 's', ACTION_RESCUE
},
7162 { 'S', ACTION_RESCUE
},
7163 { 'q', ACTION_RELOAD
},
7164 { 'Q', ACTION_RELOAD
},
7165 { 'u', ACTION_REEXEC
},
7166 { 'U', ACTION_REEXEC
}
7175 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7190 assert_not_reached("Unhandled option");
7193 if (optind
>= argc
) {
7194 log_error("%s: required argument missing.", program_invocation_short_name
);
7198 if (optind
+ 1 < argc
) {
7199 log_error("Too many arguments.");
7203 if (strlen(argv
[optind
]) != 1) {
7204 log_error("Expected single character argument.");
7208 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7209 if (table
[i
].from
== argv
[optind
][0])
7212 if (i
>= ELEMENTSOF(table
)) {
7213 log_error("Unknown command '%s'.", argv
[optind
]);
7217 arg_action
= table
[i
].to
;
7224 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7230 static const struct option options
[] = {
7231 { "help", no_argument
, NULL
, ARG_HELP
},
7240 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7251 assert_not_reached("Unhandled option");
7254 if (optind
< argc
) {
7255 log_error("Too many arguments.");
7262 static int parse_argv(int argc
, char *argv
[]) {
7266 if (program_invocation_short_name
) {
7268 if (strstr(program_invocation_short_name
, "halt")) {
7269 arg_action
= ACTION_HALT
;
7270 return halt_parse_argv(argc
, argv
);
7271 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7272 arg_action
= ACTION_POWEROFF
;
7273 return halt_parse_argv(argc
, argv
);
7274 } else if (strstr(program_invocation_short_name
, "reboot")) {
7276 arg_action
= ACTION_KEXEC
;
7278 arg_action
= ACTION_REBOOT
;
7279 return halt_parse_argv(argc
, argv
);
7280 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7281 arg_action
= ACTION_POWEROFF
;
7282 return shutdown_parse_argv(argc
, argv
);
7283 } else if (strstr(program_invocation_short_name
, "init")) {
7285 if (sd_booted() > 0) {
7286 arg_action
= _ACTION_INVALID
;
7287 return telinit_parse_argv(argc
, argv
);
7289 /* Hmm, so some other init system is
7290 * running, we need to forward this
7291 * request to it. For now we simply
7292 * guess that it is Upstart. */
7294 execv(TELINIT
, argv
);
7296 log_error("Couldn't find an alternative telinit implementation to spawn.");
7300 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7301 arg_action
= ACTION_RUNLEVEL
;
7302 return runlevel_parse_argv(argc
, argv
);
7306 arg_action
= ACTION_SYSTEMCTL
;
7307 return systemctl_parse_argv(argc
, argv
);
7310 #ifdef HAVE_SYSV_COMPAT
7311 _pure_
static int action_to_runlevel(void) {
7313 static const char table
[_ACTION_MAX
] = {
7314 [ACTION_HALT
] = '0',
7315 [ACTION_POWEROFF
] = '0',
7316 [ACTION_REBOOT
] = '6',
7317 [ACTION_RUNLEVEL2
] = '2',
7318 [ACTION_RUNLEVEL3
] = '3',
7319 [ACTION_RUNLEVEL4
] = '4',
7320 [ACTION_RUNLEVEL5
] = '5',
7321 [ACTION_RESCUE
] = '1'
7324 assert(arg_action
< _ACTION_MAX
);
7326 return table
[arg_action
];
7330 static int talk_initctl(void) {
7331 #ifdef HAVE_SYSV_COMPAT
7332 struct init_request request
= {
7333 .magic
= INIT_MAGIC
,
7335 .cmd
= INIT_CMD_RUNLVL
7338 _cleanup_close_
int fd
= -1;
7342 rl
= action_to_runlevel();
7346 request
.runlevel
= rl
;
7348 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7350 if (errno
== ENOENT
)
7353 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7356 r
= loop_write(fd
, &request
, sizeof(request
), false);
7358 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7366 static int systemctl_main(int argc
, char *argv
[]) {
7368 static const Verb verbs
[] = {
7369 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7370 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7371 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7372 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7373 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7374 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7375 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7376 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7377 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7378 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7379 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7380 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7381 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7382 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7383 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7384 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7385 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7386 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7387 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7388 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7389 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7390 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7391 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7392 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7393 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7394 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7395 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7396 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7397 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7398 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7399 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7400 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7401 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7402 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7403 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7404 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7405 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7406 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7407 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7408 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7409 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7410 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7411 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7412 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7413 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7414 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7415 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7416 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7417 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7418 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7419 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7420 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7421 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7422 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7423 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7424 { "link", 2, VERB_ANY
, 0, enable_unit
},
7425 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7426 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7427 { "set-default", 2, 2, 0, set_default
},
7428 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7429 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7430 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7431 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7432 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7433 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7437 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7440 static int reload_with_fallback(void) {
7442 /* First, try systemd via D-Bus. */
7443 if (daemon_reload(0, NULL
, NULL
) >= 0)
7446 /* Nothing else worked, so let's try signals */
7447 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7449 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7450 return log_error_errno(errno
, "kill() failed: %m");
7455 static int start_with_fallback(void) {
7457 /* First, try systemd via D-Bus. */
7458 if (start_unit(0, NULL
, NULL
) >= 0)
7461 /* Nothing else worked, so let's try
7463 if (talk_initctl() > 0)
7466 log_error("Failed to talk to init daemon.");
7470 static int halt_now(enum action a
) {
7472 /* The kernel will automaticall flush ATA disks and suchlike
7473 * on reboot(), but the file systems need to be synce'd
7474 * explicitly in advance. */
7477 /* Make sure C-A-D is handled by the kernel from this point
7479 (void) reboot(RB_ENABLE_CAD
);
7484 log_info("Halting.");
7485 (void) reboot(RB_HALT_SYSTEM
);
7488 case ACTION_POWEROFF
:
7489 log_info("Powering off.");
7490 (void) reboot(RB_POWER_OFF
);
7494 case ACTION_REBOOT
: {
7495 _cleanup_free_
char *param
= NULL
;
7497 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7498 log_info("Rebooting with argument '%s'.", param
);
7499 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7502 log_info("Rebooting.");
7503 (void) reboot(RB_AUTOBOOT
);
7508 assert_not_reached("Unknown action.");
7512 static int logind_schedule_shutdown(void) {
7515 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7516 char date
[FORMAT_TIMESTAMP_MAX
];
7521 (void) logind_set_wall_message();
7523 r
= acquire_bus(BUS_FULL
, &bus
);
7527 switch (arg_action
) {
7531 case ACTION_POWEROFF
:
7532 action
= "poweroff";
7547 action
= strjoina("dry-", action
);
7549 r
= sd_bus_call_method(
7551 "org.freedesktop.login1",
7552 "/org/freedesktop/login1",
7553 "org.freedesktop.login1.Manager",
7561 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7563 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7566 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7571 static int halt_main(void) {
7574 r
= logind_check_inhibitors(arg_action
);
7579 return logind_schedule_shutdown();
7581 if (geteuid() != 0) {
7582 if (arg_dry
|| arg_force
> 0) {
7583 log_error("Must be root.");
7587 /* Try logind if we are a normal user and no special
7588 * mode applies. Maybe PolicyKit allows us to shutdown
7590 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7591 r
= logind_reboot(arg_action
);
7594 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7595 /* requested operation is not
7596 * supported on the local system or
7597 * already in progress */
7599 /* on all other errors, try low-level operation */
7603 if (!arg_dry
&& !arg_force
)
7604 return start_with_fallback();
7606 assert(geteuid() == 0);
7609 if (sd_booted() > 0)
7610 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7612 r
= utmp_put_shutdown();
7614 log_warning_errno(r
, "Failed to write utmp record: %m");
7621 r
= halt_now(arg_action
);
7622 return log_error_errno(r
, "Failed to reboot: %m");
7625 static int runlevel_main(void) {
7626 int r
, runlevel
, previous
;
7628 r
= utmp_get_runlevel(&runlevel
, &previous
);
7635 previous
<= 0 ? 'N' : previous
,
7636 runlevel
<= 0 ? 'N' : runlevel
);
7641 static int logind_cancel_shutdown(void) {
7643 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7647 r
= acquire_bus(BUS_FULL
, &bus
);
7651 (void) logind_set_wall_message();
7653 r
= sd_bus_call_method(
7655 "org.freedesktop.login1",
7656 "/org/freedesktop/login1",
7657 "org.freedesktop.login1.Manager",
7658 "CancelScheduledShutdown",
7662 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7666 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7671 int main(int argc
, char*argv
[]) {
7674 setlocale(LC_ALL
, "");
7675 log_parse_environment();
7678 /* Explicitly not on_tty() to avoid setting cached value.
7679 * This becomes relevant for piping output which might be
7681 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7683 r
= parse_argv(argc
, argv
);
7687 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7688 log_info("Running in chroot, ignoring request.");
7693 /* systemctl_main() will print an error message for the bus
7694 * connection, but only if it needs to */
7696 switch (arg_action
) {
7698 case ACTION_SYSTEMCTL
:
7699 r
= systemctl_main(argc
, argv
);
7703 case ACTION_POWEROFF
:
7709 case ACTION_RUNLEVEL2
:
7710 case ACTION_RUNLEVEL3
:
7711 case ACTION_RUNLEVEL4
:
7712 case ACTION_RUNLEVEL5
:
7714 case ACTION_EMERGENCY
:
7715 case ACTION_DEFAULT
:
7716 r
= start_with_fallback();
7721 r
= reload_with_fallback();
7724 case ACTION_CANCEL_SHUTDOWN
:
7725 r
= logind_cancel_shutdown();
7728 case ACTION_RUNLEVEL
:
7729 r
= runlevel_main();
7732 case _ACTION_INVALID
:
7734 assert_not_reached("Unknown action");
7739 ask_password_agent_close();
7740 polkit_agent_close();
7742 strv_free(arg_types
);
7743 strv_free(arg_states
);
7744 strv_free(arg_properties
);
7746 strv_free(arg_wall
);
7751 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7753 return r
< 0 ? EXIT_FAILURE
: r
;