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 check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
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 pager_open_if_enabled(void) {
211 static void ask_password_agent_open_if_enabled(void) {
213 /* Open the password agent as a child process if necessary */
215 if (!arg_ask_password
)
218 if (arg_scope
!= UNIT_FILE_SYSTEM
)
221 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
224 ask_password_agent_open();
227 static void polkit_agent_open_if_enabled(void) {
229 /* Open the polkit agent as a child process if necessary */
231 if (!arg_ask_password
)
234 if (arg_scope
!= UNIT_FILE_SYSTEM
)
237 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
243 static OutputFlags
get_output_flags(void) {
245 arg_all
* OUTPUT_SHOW_ALL
|
246 arg_full
* OUTPUT_FULL_WIDTH
|
247 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
248 colors_enabled() * OUTPUT_COLOR
|
249 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
252 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
255 if (!sd_bus_error_is_set(error
))
258 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
259 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
260 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
261 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
262 return EXIT_NOPERMISSION
;
264 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
265 return EXIT_NOTINSTALLED
;
267 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
268 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
269 return EXIT_NOTIMPLEMENTED
;
271 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
272 return EXIT_NOTCONFIGURED
;
280 static bool install_client_side(void) {
282 /* Decides when to execute enable/disable/... operations
283 * client-side rather than server-side. */
285 if (running_in_chroot() > 0)
288 if (sd_booted() <= 0)
291 if (!isempty(arg_root
))
294 if (arg_scope
== UNIT_FILE_GLOBAL
)
297 /* Unsupported environment variable, mostly for debugging purposes */
298 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
304 static int compare_unit_info(const void *a
, const void *b
) {
305 const UnitInfo
*u
= a
, *v
= b
;
309 /* First, order by machine */
310 if (!u
->machine
&& v
->machine
)
312 if (u
->machine
&& !v
->machine
)
314 if (u
->machine
&& v
->machine
) {
315 r
= strcasecmp(u
->machine
, v
->machine
);
320 /* Second, order by unit type */
321 d1
= strrchr(u
->id
, '.');
322 d2
= strrchr(v
->id
, '.');
324 r
= strcasecmp(d1
, d2
);
329 /* Third, order by name */
330 return strcasecmp(u
->id
, v
->id
);
333 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
334 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
340 dot
= strrchr(u
->id
, '.');
344 if (!strv_find(arg_types
, dot
+1))
354 if (streq(u
->active_state
, "inactive") || u
->following
[0])
360 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
361 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
363 unsigned n_shown
= 0;
366 max_id_len
= strlen("UNIT");
367 load_len
= strlen("LOAD");
368 active_len
= strlen("ACTIVE");
369 sub_len
= strlen("SUB");
370 job_len
= strlen("JOB");
373 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
374 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
375 load_len
= MAX(load_len
, strlen(u
->load_state
));
376 active_len
= MAX(active_len
, strlen(u
->active_state
));
377 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
379 if (u
->job_id
!= 0) {
380 job_len
= MAX(job_len
, strlen(u
->job_type
));
384 if (!arg_no_legend
&&
385 (streq(u
->active_state
, "failed") ||
386 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
390 if (!arg_full
&& original_stdout_is_tty
) {
393 id_len
= MIN(max_id_len
, 25u);
394 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
397 basic_len
+= job_len
+ 1;
399 if (basic_len
< (unsigned) columns()) {
400 unsigned extra_len
, incr
;
401 extra_len
= columns() - basic_len
;
403 /* Either UNIT already got 25, or is fully satisfied.
404 * Grant up to 25 to DESC now. */
405 incr
= MIN(extra_len
, 25u);
409 /* split the remaining space between UNIT and DESC,
410 * but do not give UNIT more than it needs. */
412 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
414 desc_len
+= extra_len
- incr
;
420 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
421 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
422 const char *on_loaded
= "", *off_loaded
= "";
423 const char *on_active
= "", *off_active
= "";
424 const char *on_circle
= "", *off_circle
= "";
428 if (!n_shown
&& !arg_no_legend
) {
433 printf("%-*s %-*s %-*s %-*s ",
436 active_len
, "ACTIVE",
440 printf("%-*s ", job_len
, "JOB");
442 if (!arg_full
&& arg_no_pager
)
443 printf("%.*s\n", desc_len
, "DESCRIPTION");
445 printf("%s\n", "DESCRIPTION");
450 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
451 on_loaded
= ansi_highlight_red();
452 on_circle
= ansi_highlight_yellow();
453 off_loaded
= off_circle
= ansi_normal();
455 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
456 on_circle
= on_active
= ansi_highlight_red();
457 off_circle
= off_active
= ansi_normal();
462 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
471 e
= ellipsize(id
, id_len
, 33);
479 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
481 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
482 on_active
, id_len
, id
, off_active
,
483 on_loaded
, load_len
, u
->load_state
, off_loaded
,
484 on_active
, active_len
, u
->active_state
,
485 sub_len
, u
->sub_state
, off_active
,
486 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
489 printf("%.*s\n", desc_len
, u
->description
);
491 printf("%s\n", u
->description
);
494 if (!arg_no_legend
) {
495 const char *on
, *off
;
499 "LOAD = Reflects whether the unit definition was properly loaded.\n"
500 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
501 "SUB = The low-level unit activation state, values depend on unit type.");
502 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
503 on
= ansi_highlight();
506 on
= ansi_highlight_red();
511 printf("%s%u loaded units listed.%s\n"
512 "To show all installed unit files use 'systemctl list-unit-files'.\n",
515 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
516 "To show all installed unit files use 'systemctl list-unit-files'.\n",
523 static int get_unit_list(
527 UnitInfo
**unit_infos
,
529 sd_bus_message
**_reply
) {
531 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
532 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
533 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
542 r
= sd_bus_message_new_method_call(
545 "org.freedesktop.systemd1",
546 "/org/freedesktop/systemd1",
547 "org.freedesktop.systemd1.Manager",
548 "ListUnitsFiltered");
551 return bus_log_create_error(r
);
553 r
= sd_bus_message_append_strv(m
, arg_states
);
555 return bus_log_create_error(r
);
557 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
559 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
561 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
563 return bus_log_parse_error(r
);
565 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
568 if (!output_show_unit(&u
, patterns
))
571 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
574 (*unit_infos
)[c
++] = u
;
577 return bus_log_parse_error(r
);
579 r
= sd_bus_message_exit_container(reply
);
581 return bus_log_parse_error(r
);
589 static void message_set_freep(Set
**set
) {
592 while ((m
= set_steal_first(*set
)))
593 sd_bus_message_unref(m
);
598 static int get_unit_list_recursive(
601 UnitInfo
**_unit_infos
,
605 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
606 _cleanup_(message_set_freep
) Set
*replies
;
607 sd_bus_message
*reply
;
615 replies
= set_new(NULL
);
619 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
623 r
= set_put(replies
, reply
);
625 sd_bus_message_unref(reply
);
630 _cleanup_strv_free_
char **machines
= NULL
;
633 r
= sd_get_machine_names(&machines
);
635 return log_error_errno(r
, "Failed to get machine names: %m");
637 STRV_FOREACH(i
, machines
) {
638 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
641 r
= sd_bus_open_system_machine(&container
, *i
);
643 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
647 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
653 r
= set_put(replies
, reply
);
655 sd_bus_message_unref(reply
);
660 *_machines
= machines
;
665 *_unit_infos
= unit_infos
;
674 static int list_units(int argc
, char *argv
[], void *userdata
) {
675 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
676 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
677 _cleanup_strv_free_
char **machines
= NULL
;
681 pager_open_if_enabled();
683 r
= acquire_bus(BUS_MANAGER
, &bus
);
687 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
691 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
692 return output_units_list(unit_infos
, r
);
695 static int get_triggered_units(
700 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
707 r
= sd_bus_get_property_strv(
709 "org.freedesktop.systemd1",
711 "org.freedesktop.systemd1.Unit",
716 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
721 static int get_listening(
723 const char* unit_path
,
726 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
727 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
728 const char *type
, *path
;
731 r
= sd_bus_get_property(
733 "org.freedesktop.systemd1",
735 "org.freedesktop.systemd1.Socket",
741 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
743 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
745 return bus_log_parse_error(r
);
747 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
749 r
= strv_extend(listening
, type
);
753 r
= strv_extend(listening
, path
);
760 return bus_log_parse_error(r
);
762 r
= sd_bus_message_exit_container(reply
);
764 return bus_log_parse_error(r
);
776 /* Note: triggered is a list here, although it almost certainly
777 * will always be one unit. Nevertheless, dbus API allows for multiple
778 * values, so let's follow that. */
781 /* The strv above is shared. free is set only in the first one. */
785 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
791 if (!a
->machine
&& b
->machine
)
793 if (a
->machine
&& !b
->machine
)
795 if (a
->machine
&& b
->machine
) {
796 o
= strcasecmp(a
->machine
, b
->machine
);
801 o
= strcmp(a
->path
, b
->path
);
803 o
= strcmp(a
->type
, b
->type
);
808 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
809 struct socket_info
*s
;
810 unsigned pathlen
= strlen("LISTEN"),
811 typelen
= strlen("TYPE") * arg_show_types
,
812 socklen
= strlen("UNIT"),
813 servlen
= strlen("ACTIVATES");
814 const char *on
, *off
;
816 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
820 socklen
= MAX(socklen
, strlen(s
->id
));
822 typelen
= MAX(typelen
, strlen(s
->type
));
823 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
825 STRV_FOREACH(a
, s
->triggered
)
826 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
827 servlen
= MAX(servlen
, tmp
);
832 printf("%-*s %-*.*s%-*s %s\n",
834 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
838 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
839 _cleanup_free_
char *j
= NULL
;
844 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
852 printf("%-*s %-*s %-*s",
853 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
856 pathlen
, path
, socklen
, s
->id
);
857 STRV_FOREACH(a
, s
->triggered
)
859 a
== s
->triggered
? "" : ",", *a
);
863 on
= ansi_highlight();
868 on
= ansi_highlight_red();
872 if (!arg_no_legend
) {
873 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
875 printf("Pass --all to see loaded but inactive sockets, too.\n");
881 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
882 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
883 _cleanup_strv_free_
char **machines
= NULL
;
884 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
885 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
887 struct socket_info
*s
;
893 pager_open_if_enabled();
895 r
= acquire_bus(BUS_MANAGER
, &bus
);
899 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
903 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
904 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
907 if (!endswith(u
->id
, ".socket"))
910 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
914 c
= get_listening(bus
, u
->unit_path
, &listening
);
920 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
925 for (i
= 0; i
< c
; i
++)
926 socket_infos
[cs
+ i
] = (struct socket_info
) {
927 .machine
= u
->machine
,
929 .type
= listening
[i
*2],
930 .path
= listening
[i
*2 + 1],
931 .triggered
= triggered
,
932 .own_triggered
= i
==0,
935 /* from this point on we will cleanup those socket_infos */
938 listening
= triggered
= NULL
; /* avoid cleanup */
941 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
942 (__compar_fn_t
) socket_info_compare
);
944 output_sockets_list(socket_infos
, cs
);
947 assert(cs
== 0 || socket_infos
);
948 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
951 if (s
->own_triggered
)
952 strv_free(s
->triggered
);
958 static int get_next_elapse(
961 dual_timestamp
*next
) {
963 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
971 r
= sd_bus_get_property_trivial(
973 "org.freedesktop.systemd1",
975 "org.freedesktop.systemd1.Timer",
976 "NextElapseUSecMonotonic",
981 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
983 r
= sd_bus_get_property_trivial(
985 "org.freedesktop.systemd1",
987 "org.freedesktop.systemd1.Timer",
988 "NextElapseUSecRealtime",
993 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
999 static int get_last_trigger(
1004 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1011 r
= sd_bus_get_property_trivial(
1013 "org.freedesktop.systemd1",
1015 "org.freedesktop.systemd1.Timer",
1021 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1027 const char* machine
;
1030 usec_t last_trigger
;
1034 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1040 if (!a
->machine
&& b
->machine
)
1042 if (a
->machine
&& !b
->machine
)
1044 if (a
->machine
&& b
->machine
) {
1045 o
= strcasecmp(a
->machine
, b
->machine
);
1050 if (a
->next_elapse
< b
->next_elapse
)
1052 if (a
->next_elapse
> b
->next_elapse
)
1055 return strcmp(a
->id
, b
->id
);
1058 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1059 struct timer_info
*t
;
1061 nextlen
= strlen("NEXT"),
1062 leftlen
= strlen("LEFT"),
1063 lastlen
= strlen("LAST"),
1064 passedlen
= strlen("PASSED"),
1065 unitlen
= strlen("UNIT"),
1066 activatelen
= strlen("ACTIVATES");
1068 const char *on
, *off
;
1070 assert(timer_infos
|| n
== 0);
1072 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1076 if (t
->next_elapse
> 0) {
1077 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1079 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1080 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1082 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1083 leftlen
= MAX(leftlen
, strlen(trel
));
1086 if (t
->last_trigger
> 0) {
1087 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1089 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1090 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1092 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1093 passedlen
= MAX(passedlen
, strlen(trel
));
1096 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1098 STRV_FOREACH(a
, t
->triggered
)
1099 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1101 activatelen
= MAX(activatelen
, ul
);
1106 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1110 passedlen
, "PASSED",
1114 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1115 _cleanup_free_
char *j
= NULL
;
1117 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1118 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1121 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1122 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1124 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1125 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1128 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1135 printf("%-*s %-*s %-*s %-*s %-*s",
1136 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1138 STRV_FOREACH(a
, t
->triggered
)
1140 a
== t
->triggered
? "" : ",", *a
);
1144 on
= ansi_highlight();
1145 off
= ansi_normal();
1149 on
= ansi_highlight_red();
1150 off
= ansi_normal();
1153 if (!arg_no_legend
) {
1154 printf("%s%u timers listed.%s\n", on
, n
, off
);
1156 printf("Pass --all to see loaded but inactive timers, too.\n");
1162 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1168 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1171 if (next
->monotonic
> nw
->monotonic
)
1172 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1174 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1176 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1177 next_elapse
= MIN(converted
, next
->realtime
);
1179 next_elapse
= converted
;
1182 next_elapse
= next
->realtime
;
1187 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1188 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1189 _cleanup_strv_free_
char **machines
= NULL
;
1190 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1191 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1192 struct timer_info
*t
;
1200 pager_open_if_enabled();
1202 r
= acquire_bus(BUS_MANAGER
, &bus
);
1206 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1210 dual_timestamp_get(&nw
);
1212 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1213 _cleanup_strv_free_
char **triggered
= NULL
;
1214 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1217 if (!endswith(u
->id
, ".timer"))
1220 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1224 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1228 get_last_trigger(bus
, u
->unit_path
, &last
);
1230 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1235 m
= calc_next_elapse(&nw
, &next
);
1237 timer_infos
[c
++] = (struct timer_info
) {
1238 .machine
= u
->machine
,
1241 .last_trigger
= last
,
1242 .triggered
= triggered
,
1245 triggered
= NULL
; /* avoid cleanup */
1248 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1249 (__compar_fn_t
) timer_info_compare
);
1251 output_timers_list(timer_infos
, c
);
1254 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1255 strv_free(t
->triggered
);
1260 static int compare_unit_file_list(const void *a
, const void *b
) {
1261 const char *d1
, *d2
;
1262 const UnitFileList
*u
= a
, *v
= b
;
1264 d1
= strrchr(u
->path
, '.');
1265 d2
= strrchr(v
->path
, '.');
1270 r
= strcasecmp(d1
, d2
);
1275 return strcasecmp(basename(u
->path
), basename(v
->path
));
1278 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1279 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1282 if (!strv_isempty(arg_types
)) {
1285 dot
= strrchr(u
->path
, '.');
1289 if (!strv_find(arg_types
, dot
+1))
1293 if (!strv_isempty(arg_states
) &&
1294 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1300 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1301 unsigned max_id_len
, id_cols
, state_cols
;
1302 const UnitFileList
*u
;
1304 max_id_len
= strlen("UNIT FILE");
1305 state_cols
= strlen("STATE");
1307 for (u
= units
; u
< units
+ c
; u
++) {
1308 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1309 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1313 unsigned basic_cols
;
1315 id_cols
= MIN(max_id_len
, 25u);
1316 basic_cols
= 1 + id_cols
+ state_cols
;
1317 if (basic_cols
< (unsigned) columns())
1318 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1320 id_cols
= max_id_len
;
1323 printf("%-*s %-*s\n",
1324 id_cols
, "UNIT FILE",
1325 state_cols
, "STATE");
1327 for (u
= units
; u
< units
+ c
; u
++) {
1328 _cleanup_free_
char *e
= NULL
;
1329 const char *on
, *off
;
1332 if (IN_SET(u
->state
,
1334 UNIT_FILE_MASKED_RUNTIME
,
1337 on
= ansi_highlight_red();
1338 off
= ansi_normal();
1339 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1340 on
= ansi_highlight_green();
1341 off
= ansi_normal();
1345 id
= basename(u
->path
);
1347 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1349 printf("%-*s %s%-*s%s\n",
1350 id_cols
, e
? e
: id
,
1351 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1355 printf("\n%u unit files listed.\n", c
);
1358 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1359 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1360 _cleanup_free_ UnitFileList
*units
= NULL
;
1368 pager_open_if_enabled();
1370 if (install_client_side()) {
1376 h
= hashmap_new(&string_hash_ops
);
1380 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1382 unit_file_list_free(h
);
1383 return log_error_errno(r
, "Failed to get unit file list: %m");
1386 n_units
= hashmap_size(h
);
1388 units
= new(UnitFileList
, n_units
);
1389 if (!units
&& n_units
> 0) {
1390 unit_file_list_free(h
);
1394 HASHMAP_FOREACH(u
, h
, i
) {
1395 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1402 assert(c
<= n_units
);
1405 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1408 r
= acquire_bus(BUS_MANAGER
, &bus
);
1412 r
= sd_bus_call_method(
1414 "org.freedesktop.systemd1",
1415 "/org/freedesktop/systemd1",
1416 "org.freedesktop.systemd1.Manager",
1422 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1424 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1426 return bus_log_parse_error(r
);
1428 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1430 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1433 units
[c
] = (struct UnitFileList
) {
1435 unit_file_state_from_string(state
)
1438 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1443 return bus_log_parse_error(r
);
1445 r
= sd_bus_message_exit_container(reply
);
1447 return bus_log_parse_error(r
);
1450 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1451 output_unit_file_list(units
, c
);
1453 if (install_client_side()) {
1454 for (unit
= units
; unit
< units
+ c
; unit
++)
1461 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1462 _cleanup_free_
char *n
= NULL
;
1463 size_t max_len
= MAX(columns(),20u);
1469 for (i
= level
- 1; i
>= 0; i
--) {
1471 if (len
> max_len
- 3 && !arg_full
) {
1472 printf("%s...\n",max_len
% 2 ? "" : " ");
1475 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1479 if (len
> max_len
- 3 && !arg_full
) {
1480 printf("%s...\n",max_len
% 2 ? "" : " ");
1484 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1488 printf("%s\n", name
);
1492 n
= ellipsize(name
, max_len
-len
, 100);
1500 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1502 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1503 [DEPENDENCY_FORWARD
] = "Requires\0"
1508 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1513 [DEPENDENCY_AFTER
] = "After\0",
1514 [DEPENDENCY_BEFORE
] = "Before\0",
1517 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1518 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1519 _cleanup_strv_free_
char **ret
= NULL
;
1520 _cleanup_free_
char *path
= NULL
;
1526 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1528 path
= unit_dbus_path_from_name(name
);
1532 r
= sd_bus_call_method(
1534 "org.freedesktop.systemd1",
1536 "org.freedesktop.DBus.Properties",
1540 "s", "org.freedesktop.systemd1.Unit");
1542 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1544 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1546 return bus_log_parse_error(r
);
1548 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1551 r
= sd_bus_message_read(reply
, "s", &prop
);
1553 return bus_log_parse_error(r
);
1555 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1556 r
= sd_bus_message_skip(reply
, "v");
1558 return bus_log_parse_error(r
);
1561 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1563 return bus_log_parse_error(r
);
1565 r
= bus_message_read_strv_extend(reply
, &ret
);
1567 return bus_log_parse_error(r
);
1569 r
= sd_bus_message_exit_container(reply
);
1571 return bus_log_parse_error(r
);
1574 r
= sd_bus_message_exit_container(reply
);
1576 return bus_log_parse_error(r
);
1580 return bus_log_parse_error(r
);
1582 r
= sd_bus_message_exit_container(reply
);
1584 return bus_log_parse_error(r
);
1592 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1593 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1595 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1597 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1600 return strcasecmp(*a
, *b
);
1603 static int list_dependencies_one(
1608 unsigned int branches
) {
1610 _cleanup_strv_free_
char **deps
= NULL
;
1618 r
= strv_extend(units
, name
);
1622 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1626 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1628 STRV_FOREACH(c
, deps
) {
1629 if (strv_contains(*units
, *c
)) {
1631 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1644 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1645 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1646 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1649 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1653 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1654 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1661 strv_remove(*units
, name
);
1666 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1667 _cleanup_strv_free_
char **units
= NULL
;
1668 _cleanup_free_
char *unit
= NULL
;
1674 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1676 return log_error_errno(r
, "Failed to mangle unit name: %m");
1680 u
= SPECIAL_DEFAULT_TARGET
;
1682 pager_open_if_enabled();
1684 r
= acquire_bus(BUS_MANAGER
, &bus
);
1690 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1693 struct machine_info
{
1697 char *control_group
;
1698 uint32_t n_failed_units
;
1703 static const struct bus_properties_map machine_info_property_map
[] = {
1704 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1705 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1706 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1707 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1708 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1712 static void machine_info_clear(struct machine_info
*info
) {
1716 free(info
->control_group
);
1721 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1727 for (i
= 0; i
< n
; i
++)
1728 machine_info_clear(&machine_infos
[i
]);
1730 free(machine_infos
);
1733 static int compare_machine_info(const void *a
, const void *b
) {
1734 const struct machine_info
*u
= a
, *v
= b
;
1736 if (u
->is_host
!= v
->is_host
)
1737 return u
->is_host
> v
->is_host
? -1 : 1;
1739 return strcasecmp(u
->name
, v
->name
);
1742 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1743 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1749 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1756 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1763 static bool output_show_machine(const char *name
, char **patterns
) {
1764 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1767 static int get_machine_list(
1769 struct machine_info
**_machine_infos
,
1772 struct machine_info
*machine_infos
= NULL
;
1773 _cleanup_strv_free_
char **m
= NULL
;
1774 _cleanup_free_
char *hn
= NULL
;
1779 hn
= gethostname_malloc();
1783 if (output_show_machine(hn
, patterns
)) {
1784 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1787 machine_infos
[c
].is_host
= true;
1788 machine_infos
[c
].name
= hn
;
1791 get_machine_properties(bus
, &machine_infos
[c
]);
1795 r
= sd_get_machine_names(&m
);
1797 return log_error_errno(r
, "Failed to get machine list: %m");
1799 STRV_FOREACH(i
, m
) {
1800 _cleanup_free_
char *class = NULL
;
1802 if (!output_show_machine(*i
, patterns
))
1805 sd_machine_get_class(*i
, &class);
1806 if (!streq_ptr(class, "container"))
1809 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1810 free_machines_list(machine_infos
, c
);
1814 machine_infos
[c
].is_host
= false;
1815 machine_infos
[c
].name
= strdup(*i
);
1816 if (!machine_infos
[c
].name
) {
1817 free_machines_list(machine_infos
, c
);
1821 get_machine_properties(NULL
, &machine_infos
[c
]);
1825 *_machine_infos
= machine_infos
;
1829 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1830 struct machine_info
*m
;
1833 namelen
= sizeof("NAME") - 1,
1834 statelen
= sizeof("STATE") - 1,
1835 failedlen
= sizeof("FAILED") - 1,
1836 jobslen
= sizeof("JOBS") - 1;
1838 assert(machine_infos
|| n
== 0);
1840 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1841 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1842 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1843 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1844 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1846 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1850 if (!arg_no_legend
) {
1854 printf("%-*s %-*s %-*s %-*s\n",
1857 failedlen
, "FAILED",
1861 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1862 const char *on_state
= "", *off_state
= "";
1863 const char *on_failed
= "", *off_failed
= "";
1864 bool circle
= false;
1866 if (streq_ptr(m
->state
, "degraded")) {
1867 on_state
= ansi_highlight_red();
1868 off_state
= ansi_normal();
1870 } else if (!streq_ptr(m
->state
, "running")) {
1871 on_state
= ansi_highlight_yellow();
1872 off_state
= ansi_normal();
1876 if (m
->n_failed_units
> 0) {
1877 on_failed
= ansi_highlight_red();
1878 off_failed
= ansi_normal();
1880 on_failed
= off_failed
= "";
1883 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1886 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1887 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1888 on_state
, statelen
, strna(m
->state
), off_state
,
1889 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1890 jobslen
, m
->n_jobs
);
1892 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1893 namelen
, strna(m
->name
),
1894 on_state
, statelen
, strna(m
->state
), off_state
,
1895 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1896 jobslen
, m
->n_jobs
);
1900 printf("\n%u machines listed.\n", n
);
1903 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1904 struct machine_info
*machine_infos
= NULL
;
1908 if (geteuid() != 0) {
1909 log_error("Must be root.");
1913 pager_open_if_enabled();
1915 r
= acquire_bus(BUS_MANAGER
, &bus
);
1919 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1923 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1924 output_machines_list(machine_infos
, r
);
1925 free_machines_list(machine_infos
, r
);
1930 static int get_default(int argc
, char *argv
[], void *userdata
) {
1931 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1932 _cleanup_free_
char *_path
= NULL
;
1936 if (install_client_side()) {
1937 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1939 return log_error_errno(r
, "Failed to get default target: %m");
1943 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1946 r
= acquire_bus(BUS_MANAGER
, &bus
);
1950 r
= sd_bus_call_method(
1952 "org.freedesktop.systemd1",
1953 "/org/freedesktop/systemd1",
1954 "org.freedesktop.systemd1.Manager",
1960 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1962 r
= sd_bus_message_read(reply
, "s", &path
);
1964 return bus_log_parse_error(r
);
1968 printf("%s\n", path
);
1973 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1976 assert(changes
|| n_changes
== 0);
1978 for (i
= 0; i
< n_changes
; i
++) {
1979 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1980 log_info("Created symlink %s, pointing to %s.", changes
[i
].path
, changes
[i
].source
);
1982 log_info("Removed symlink %s.", changes
[i
].path
);
1986 static int set_default(int argc
, char *argv
[], void *userdata
) {
1987 _cleanup_free_
char *unit
= NULL
;
1993 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1995 return log_error_errno(r
, "Failed to mangle unit name: %m");
1997 if (install_client_side()) {
1998 UnitFileChange
*changes
= NULL
;
1999 unsigned n_changes
= 0;
2001 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2003 return log_error_errno(r
, "Failed to set default target: %m");
2006 dump_unit_file_changes(changes
, n_changes
);
2008 unit_file_changes_free(changes
, n_changes
);
2011 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2012 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2015 polkit_agent_open_if_enabled();
2017 r
= acquire_bus(BUS_MANAGER
, &bus
);
2021 r
= sd_bus_call_method(
2023 "org.freedesktop.systemd1",
2024 "/org/freedesktop/systemd1",
2025 "org.freedesktop.systemd1.Manager",
2031 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2033 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2037 /* Try to reload if enabled */
2039 r
= daemon_reload(argc
, argv
, userdata
);
2049 const char *name
, *type
, *state
;
2052 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2053 unsigned id_len
, unit_len
, type_len
, state_len
;
2054 const struct job_info
*j
;
2055 const char *on
, *off
;
2056 bool shorten
= false;
2058 assert(n
== 0 || jobs
);
2061 if (!arg_no_legend
) {
2062 on
= ansi_highlight_green();
2063 off
= ansi_normal();
2065 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2070 pager_open_if_enabled();
2072 id_len
= strlen("JOB");
2073 unit_len
= strlen("UNIT");
2074 type_len
= strlen("TYPE");
2075 state_len
= strlen("STATE");
2077 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2078 uint32_t id
= j
->id
;
2079 assert(j
->name
&& j
->type
&& j
->state
);
2081 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2082 unit_len
= MAX(unit_len
, strlen(j
->name
));
2083 type_len
= MAX(type_len
, strlen(j
->type
));
2084 state_len
= MAX(state_len
, strlen(j
->state
));
2087 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2088 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2093 printf("%*s %-*s %-*s %-*s\n",
2097 state_len
, "STATE");
2099 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2100 _cleanup_free_
char *e
= NULL
;
2102 if (streq(j
->state
, "running")) {
2103 on
= ansi_highlight();
2104 off
= ansi_normal();
2108 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2109 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2111 on
, unit_len
, e
? e
: j
->name
, off
,
2113 on
, state_len
, j
->state
, off
);
2116 if (!arg_no_legend
) {
2117 on
= ansi_highlight();
2118 off
= ansi_normal();
2120 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2124 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2125 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2128 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2129 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2130 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2131 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2132 _cleanup_free_
struct job_info
*jobs
= NULL
;
2138 bool skipped
= false;
2140 pager_open_if_enabled();
2142 r
= acquire_bus(BUS_MANAGER
, &bus
);
2146 r
= sd_bus_call_method(
2148 "org.freedesktop.systemd1",
2149 "/org/freedesktop/systemd1",
2150 "org.freedesktop.systemd1.Manager",
2156 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2158 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2160 return bus_log_parse_error(r
);
2162 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2163 struct job_info job
= { id
, name
, type
, state
};
2165 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2170 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2176 return bus_log_parse_error(r
);
2178 r
= sd_bus_message_exit_container(reply
);
2180 return bus_log_parse_error(r
);
2182 output_jobs_list(jobs
, c
, skipped
);
2186 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2192 return daemon_reload(argc
, argv
, userdata
);
2194 polkit_agent_open_if_enabled();
2196 r
= acquire_bus(BUS_MANAGER
, &bus
);
2200 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2201 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2205 q
= safe_atou32(*name
, &id
);
2207 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2209 q
= sd_bus_call_method(
2211 "org.freedesktop.systemd1",
2212 "/org/freedesktop/systemd1",
2213 "org.freedesktop.systemd1.Manager",
2219 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2228 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2229 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2233 /* We ignore all errors here, since this is used to show a
2236 /* We don't use unit_dbus_path_from_name() directly since we
2237 * don't want to load the unit if it isn't loaded. */
2239 r
= sd_bus_call_method(
2241 "org.freedesktop.systemd1",
2242 "/org/freedesktop/systemd1",
2243 "org.freedesktop.systemd1.Manager",
2251 r
= sd_bus_message_read(reply
, "o", &path
);
2255 r
= sd_bus_get_property_trivial(
2257 "org.freedesktop.systemd1",
2259 "org.freedesktop.systemd1.Unit",
2269 static void warn_unit_file_changed(const char *name
) {
2270 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2271 ansi_highlight_red(),
2274 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2277 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2284 STRV_FOREACH(p
, lp
->unit_path
) {
2285 _cleanup_free_
char *path
;
2287 path
= path_join(arg_root
, *p
, unit_name
);
2291 if (access(path
, F_OK
) == 0) {
2301 static int unit_find_paths(
2303 const char *unit_name
,
2305 char **fragment_path
,
2306 char ***dropin_paths
) {
2308 _cleanup_free_
char *path
= NULL
;
2309 _cleanup_strv_free_
char **dropins
= NULL
;
2313 * Finds where the unit is defined on disk. Returns 0 if the unit
2314 * is not found. Returns 1 if it is found, and sets
2315 * - the path to the unit in *path, if it exists on disk,
2316 * - and a strv of existing drop-ins in *dropins,
2317 * if the arg is not NULL and any dropins were found.
2321 assert(fragment_path
);
2324 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2325 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2326 _cleanup_free_
char *unit
= NULL
;
2328 unit
= unit_dbus_path_from_name(unit_name
);
2332 r
= sd_bus_get_property_string(
2334 "org.freedesktop.systemd1",
2336 "org.freedesktop.systemd1.Unit",
2341 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2344 r
= sd_bus_get_property_strv(
2346 "org.freedesktop.systemd1",
2348 "org.freedesktop.systemd1.Unit",
2353 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2356 _cleanup_set_free_ Set
*names
;
2358 names
= set_new(NULL
);
2362 r
= set_put(names
, unit_name
);
2364 return log_error_errno(r
, "Failed to add unit name: %m");
2366 r
= unit_file_find_path(lp
, unit_name
, &path
);
2371 _cleanup_free_
char *template = NULL
;
2373 r
= unit_name_template(unit_name
, &template);
2374 if (r
< 0 && r
!= -EINVAL
)
2375 return log_error_errno(r
, "Failed to determine template name: %m");
2377 r
= unit_file_find_path(lp
, template, &path
);
2384 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2392 if (!isempty(path
)) {
2393 *fragment_path
= path
;
2398 if (dropin_paths
&& !strv_isempty(dropins
)) {
2399 *dropin_paths
= dropins
;
2405 log_error("No files found for %s.", unit_name
);
2410 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2411 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2412 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2413 _cleanup_free_
char *buf
= NULL
;
2414 const char *path
, *state
;
2419 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2422 r
= sd_bus_call_method(
2424 "org.freedesktop.systemd1",
2425 "/org/freedesktop/systemd1",
2426 "org.freedesktop.systemd1.Manager",
2432 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2433 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2435 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2436 * considered inactive. */
2440 r
= sd_bus_message_read(reply
, "o", &path
);
2442 return bus_log_parse_error(r
);
2444 r
= sd_bus_get_property_string(
2446 "org.freedesktop.systemd1",
2448 "org.freedesktop.systemd1.Unit",
2453 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2461 return nulstr_contains(good_states
, state
);
2464 static int check_triggering_units(
2468 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2469 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2470 _cleanup_strv_free_
char **triggered_by
= NULL
;
2471 bool print_warning_label
= true;
2475 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2477 return log_error_errno(r
, "Failed to mangle unit name: %m");
2479 path
= unit_dbus_path_from_name(n
);
2483 r
= sd_bus_get_property_string(
2485 "org.freedesktop.systemd1",
2487 "org.freedesktop.systemd1.Unit",
2492 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2494 if (streq(state
, "masked"))
2497 r
= sd_bus_get_property_strv(
2499 "org.freedesktop.systemd1",
2501 "org.freedesktop.systemd1.Unit",
2506 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2508 STRV_FOREACH(i
, triggered_by
) {
2509 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2511 return log_error_errno(r
, "Failed to check unit: %m");
2516 if (print_warning_label
) {
2517 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2518 print_warning_label
= false;
2521 log_warning(" %s", *i
);
2527 static const struct {
2530 } unit_actions
[] = {
2531 { "start", "StartUnit" },
2532 { "stop", "StopUnit" },
2533 { "condstop", "StopUnit" },
2534 { "reload", "ReloadUnit" },
2535 { "restart", "RestartUnit" },
2536 { "try-restart", "TryRestartUnit" },
2537 { "condrestart", "TryRestartUnit" },
2538 { "reload-or-restart", "ReloadOrRestartUnit" },
2539 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2540 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2541 { "condreload", "ReloadOrTryRestartUnit" },
2542 { "force-reload", "ReloadOrTryRestartUnit" }
2545 static const char *verb_to_method(const char *verb
) {
2548 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2549 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2550 return unit_actions
[i
].method
;
2555 static const char *method_to_verb(const char *method
) {
2558 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2559 if (streq_ptr(unit_actions
[i
].method
, method
))
2560 return unit_actions
[i
].verb
;
2565 static int start_unit_one(
2570 sd_bus_error
*error
,
2571 BusWaitForJobs
*w
) {
2573 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2582 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2584 r
= sd_bus_call_method(
2586 "org.freedesktop.systemd1",
2587 "/org/freedesktop/systemd1",
2588 "org.freedesktop.systemd1.Manager",
2596 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2597 /* There's always a fallback possible for
2598 * legacy actions. */
2599 return -EADDRNOTAVAIL
;
2601 verb
= method_to_verb(method
);
2603 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2605 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2606 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2607 log_error("See system logs and 'systemctl status %s' for details.", name
);
2612 r
= sd_bus_message_read(reply
, "o", &path
);
2614 return bus_log_parse_error(r
);
2616 if (need_daemon_reload(bus
, name
) > 0)
2617 warn_unit_file_changed(name
);
2620 log_debug("Adding %s to the set", path
);
2621 r
= bus_wait_for_jobs_add(w
, path
);
2629 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2630 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2637 STRV_FOREACH(name
, names
) {
2641 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2643 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2645 return log_error_errno(r
, "Failed to mangle name: %m");
2647 if (string_is_glob(t
))
2648 r
= strv_consume(&globs
, t
);
2650 r
= strv_consume(&mangled
, t
);
2655 /* Query the manager only if any of the names are a glob, since
2656 * this is fairly expensive */
2657 if (!strv_isempty(globs
)) {
2658 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2659 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2660 size_t allocated
, n
;
2662 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2666 n
= strv_length(mangled
);
2669 for (i
= 0; i
< r
; i
++) {
2670 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2673 mangled
[n
] = strdup(unit_infos
[i
].id
);
2677 mangled
[++n
] = NULL
;
2682 mangled
= NULL
; /* do not free */
2687 static const struct {
2691 } action_table
[_ACTION_MAX
] = {
2692 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2693 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2694 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2695 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2696 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2697 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2698 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2699 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2700 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2701 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2702 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2703 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2704 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2705 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2706 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2709 static enum action
verb_to_action(const char *verb
) {
2712 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2713 if (streq_ptr(action_table
[i
].verb
, verb
))
2716 return _ACTION_INVALID
;
2719 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2720 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2721 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2722 _cleanup_strv_free_
char **names
= NULL
;
2727 ask_password_agent_open_if_enabled();
2728 polkit_agent_open_if_enabled();
2730 r
= acquire_bus(BUS_MANAGER
, &bus
);
2734 if (arg_action
== ACTION_SYSTEMCTL
) {
2737 method
= verb_to_method(argv
[0]);
2738 action
= verb_to_action(argv
[0]);
2740 if (streq(argv
[0], "isolate")) {
2744 mode
= action_table
[action
].mode
?: arg_job_mode
;
2746 one_name
= action_table
[action
].target
;
2748 assert(arg_action
< ELEMENTSOF(action_table
));
2749 assert(action_table
[arg_action
].target
);
2751 method
= "StartUnit";
2753 mode
= action_table
[arg_action
].mode
;
2754 one_name
= action_table
[arg_action
].target
;
2758 names
= strv_new(one_name
, NULL
);
2760 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2762 return log_error_errno(r
, "Failed to expand names: %m");
2765 if (!arg_no_block
) {
2766 r
= bus_wait_for_jobs_new(bus
, &w
);
2768 return log_error_errno(r
, "Could not watch jobs: %m");
2771 STRV_FOREACH(name
, names
) {
2772 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2775 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2776 if (r
>= 0 && q
< 0)
2777 r
= translate_bus_error_to_exit_status(q
, &error
);
2780 if (!arg_no_block
) {
2781 int q
, arg_count
= 1;
2782 const char* extra_args
[5] = {NULL
};
2784 /* leave first empty for the actual command name*/
2785 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2786 extra_args
[arg_count
++] = "--user";
2788 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2789 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2790 extra_args
[arg_count
++] = "-H";
2791 extra_args
[arg_count
++] = arg_host
;
2792 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2793 extra_args
[arg_count
++] = "-M";
2794 extra_args
[arg_count
++] = arg_host
;
2797 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2801 /* When stopping units, warn if they can still be triggered by
2802 * another active unit (socket, path, timer) */
2803 if (!arg_quiet
&& streq(method
, "StopUnit"))
2804 STRV_FOREACH(name
, names
)
2805 check_triggering_units(bus
, *name
);
2811 static int logind_set_wall_message(void) {
2813 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2815 _cleanup_free_
char *m
= NULL
;
2818 r
= acquire_bus(BUS_FULL
, &bus
);
2822 m
= strv_join(arg_wall
, " ");
2826 r
= sd_bus_call_method(
2828 "org.freedesktop.login1",
2829 "/org/freedesktop/login1",
2830 "org.freedesktop.login1.Manager",
2839 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2845 /* Ask systemd-logind, which might grant access to unprivileged users
2846 * through PolicyKit */
2847 static int logind_reboot(enum action a
) {
2849 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2850 const char *method
, *description
;
2854 polkit_agent_open_if_enabled();
2855 (void) logind_set_wall_message();
2857 r
= acquire_bus(BUS_FULL
, &bus
);
2865 description
= "reboot system";
2868 case ACTION_POWEROFF
:
2869 method
= "PowerOff";
2870 description
= "power off system";
2873 case ACTION_SUSPEND
:
2875 description
= "suspend system";
2878 case ACTION_HIBERNATE
:
2879 method
= "Hibernate";
2880 description
= "hibernate system";
2883 case ACTION_HYBRID_SLEEP
:
2884 method
= "HybridSleep";
2885 description
= "put system into hybrid sleep";
2892 r
= sd_bus_call_method(
2894 "org.freedesktop.login1",
2895 "/org/freedesktop/login1",
2896 "org.freedesktop.login1.Manager",
2900 "b", arg_ask_password
);
2902 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2910 static int logind_check_inhibitors(enum action a
) {
2912 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2913 _cleanup_strv_free_
char **sessions
= NULL
;
2914 const char *what
, *who
, *why
, *mode
;
2921 if (arg_ignore_inhibitors
|| arg_force
> 0)
2933 r
= acquire_bus(BUS_FULL
, &bus
);
2937 r
= sd_bus_call_method(
2939 "org.freedesktop.login1",
2940 "/org/freedesktop/login1",
2941 "org.freedesktop.login1.Manager",
2947 /* If logind is not around, then there are no inhibitors... */
2950 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2952 return bus_log_parse_error(r
);
2954 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2955 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2956 _cleanup_strv_free_
char **sv
= NULL
;
2958 if (!streq(mode
, "block"))
2961 sv
= strv_split(what
, ":");
2965 if ((pid_t
) pid
< 0)
2966 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2968 if (!strv_contains(sv
,
2973 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2976 get_process_comm(pid
, &comm
);
2977 user
= uid_to_name(uid
);
2979 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2980 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2985 return bus_log_parse_error(r
);
2987 r
= sd_bus_message_exit_container(reply
);
2989 return bus_log_parse_error(r
);
2991 /* Check for current sessions */
2992 sd_get_sessions(&sessions
);
2993 STRV_FOREACH(s
, sessions
) {
2994 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2996 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2999 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3002 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3005 sd_session_get_tty(*s
, &tty
);
3006 sd_session_get_seat(*s
, &seat
);
3007 sd_session_get_service(*s
, &service
);
3008 user
= uid_to_name(uid
);
3010 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3017 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3018 action_table
[a
].verb
);
3026 static int logind_prepare_firmware_setup(void) {
3028 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3032 r
= acquire_bus(BUS_FULL
, &bus
);
3036 r
= sd_bus_call_method(
3038 "org.freedesktop.login1",
3039 "/org/freedesktop/login1",
3040 "org.freedesktop.login1.Manager",
3041 "SetRebootToFirmwareSetup",
3046 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3050 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3055 static int prepare_firmware_setup(void) {
3058 if (!arg_firmware_setup
)
3061 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3063 r
= efi_set_reboot_to_firmware(true);
3065 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3070 return logind_prepare_firmware_setup();
3073 static int set_exit_code(uint8_t code
) {
3074 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3078 r
= acquire_bus(BUS_MANAGER
, &bus
);
3082 r
= sd_bus_call_method(
3084 "org.freedesktop.systemd1",
3085 "/org/freedesktop/systemd1",
3086 "org.freedesktop.systemd1.Manager",
3092 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3097 static int start_special(int argc
, char *argv
[], void *userdata
) {
3103 a
= verb_to_action(argv
[0]);
3105 r
= logind_check_inhibitors(a
);
3109 if (arg_force
>= 2 && geteuid() != 0) {
3110 log_error("Must be root.");
3114 r
= prepare_firmware_setup();
3118 if (a
== ACTION_REBOOT
&& argc
> 1) {
3119 r
= update_reboot_param_file(argv
[1]);
3123 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3126 /* If the exit code is not given on the command line,
3127 * don't reset it to zero: just keep it as it might
3128 * have been set previously. */
3130 r
= safe_atou8(argv
[1], &code
);
3132 return log_error_errno(r
, "Invalid exit code.");
3134 r
= set_exit_code(code
);
3139 if (arg_force
>= 2 &&
3146 if (arg_force
>= 1 &&
3153 return daemon_reload(argc
, argv
, userdata
);
3155 /* First try logind, to allow authentication with polkit */
3161 ACTION_HYBRID_SLEEP
)) {
3162 r
= logind_reboot(a
);
3165 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3166 /* requested operation is not supported or already in progress */
3169 /* On all other errors, try low-level operation */
3172 return start_unit(argc
, argv
, userdata
);
3175 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3176 _cleanup_strv_free_
char **names
= NULL
;
3182 r
= acquire_bus(BUS_MANAGER
, &bus
);
3186 r
= expand_names(bus
, args
, NULL
, &names
);
3188 return log_error_errno(r
, "Failed to expand names: %m");
3190 STRV_FOREACH(name
, names
) {
3193 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3200 /* use the given return code for the case that we won't find
3201 * any unit which matches the list */
3202 return found
? 0 : code
;
3205 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3206 /* According to LSB: 3, "program is not running" */
3207 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3210 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3211 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3214 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3215 _cleanup_strv_free_
char **names
= NULL
;
3216 char *kill_who
= NULL
, **name
;
3220 polkit_agent_open_if_enabled();
3222 r
= acquire_bus(BUS_MANAGER
, &bus
);
3227 arg_kill_who
= "all";
3229 /* --fail was specified */
3230 if (streq(arg_job_mode
, "fail"))
3231 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3233 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3235 return log_error_errno(r
, "Failed to expand names: %m");
3237 STRV_FOREACH(name
, names
) {
3238 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3240 q
= sd_bus_call_method(
3242 "org.freedesktop.systemd1",
3243 "/org/freedesktop/systemd1",
3244 "org.freedesktop.systemd1.Manager",
3248 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3250 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3259 typedef struct ExecStatusInfo
{
3267 usec_t start_timestamp
;
3268 usec_t exit_timestamp
;
3273 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3276 static void exec_status_info_free(ExecStatusInfo
*i
) {
3285 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3286 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3289 int32_t code
, status
;
3295 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3297 return bus_log_parse_error(r
);
3301 r
= sd_bus_message_read(m
, "s", &path
);
3303 return bus_log_parse_error(r
);
3305 i
->path
= strdup(path
);
3309 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3311 return bus_log_parse_error(r
);
3313 r
= sd_bus_message_read(m
,
3316 &start_timestamp
, &start_timestamp_monotonic
,
3317 &exit_timestamp
, &exit_timestamp_monotonic
,
3321 return bus_log_parse_error(r
);
3324 i
->start_timestamp
= (usec_t
) start_timestamp
;
3325 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3326 i
->pid
= (pid_t
) pid
;
3330 r
= sd_bus_message_exit_container(m
);
3332 return bus_log_parse_error(r
);
3337 typedef struct UnitStatusInfo
{
3339 const char *load_state
;
3340 const char *active_state
;
3341 const char *sub_state
;
3342 const char *unit_file_state
;
3343 const char *unit_file_preset
;
3345 const char *description
;
3346 const char *following
;
3348 char **documentation
;
3350 const char *fragment_path
;
3351 const char *source_path
;
3352 const char *control_group
;
3354 char **dropin_paths
;
3356 const char *load_error
;
3359 usec_t inactive_exit_timestamp
;
3360 usec_t inactive_exit_timestamp_monotonic
;
3361 usec_t active_enter_timestamp
;
3362 usec_t active_exit_timestamp
;
3363 usec_t inactive_enter_timestamp
;
3365 bool need_daemon_reload
;
3371 const char *status_text
;
3372 const char *pid_file
;
3376 usec_t start_timestamp
;
3377 usec_t exit_timestamp
;
3379 int exit_code
, exit_status
;
3381 usec_t condition_timestamp
;
3382 bool condition_result
;
3383 bool failed_condition_trigger
;
3384 bool failed_condition_negate
;
3385 const char *failed_condition
;
3386 const char *failed_condition_parameter
;
3388 usec_t assert_timestamp
;
3390 bool failed_assert_trigger
;
3391 bool failed_assert_negate
;
3392 const char *failed_assert
;
3393 const char *failed_assert_parameter
;
3396 unsigned n_accepted
;
3397 unsigned n_connections
;
3400 /* Pairs of type, path */
3404 const char *sysfs_path
;
3406 /* Mount, Automount */
3413 uint64_t memory_current
;
3414 uint64_t memory_limit
;
3415 uint64_t cpu_usage_nsec
;
3416 uint64_t tasks_current
;
3419 LIST_HEAD(ExecStatusInfo
, exec
);
3422 static void print_status_info(
3427 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3429 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3430 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3436 /* This shows pretty information about a unit. See
3437 * print_property() for a low-level property printer */
3439 if (streq_ptr(i
->active_state
, "failed")) {
3440 active_on
= ansi_highlight_red();
3441 active_off
= ansi_normal();
3442 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3443 active_on
= ansi_highlight_green();
3444 active_off
= ansi_normal();
3446 active_on
= active_off
= "";
3448 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3450 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3451 printf(" - %s", i
->description
);
3456 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3458 if (streq_ptr(i
->load_state
, "error")) {
3459 on
= ansi_highlight_red();
3460 off
= ansi_normal();
3464 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3466 if (i
->load_error
!= 0)
3467 printf(" Loaded: %s%s%s (Reason: %s)\n",
3468 on
, strna(i
->load_state
), off
, i
->load_error
);
3469 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3470 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3471 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3472 else if (path
&& !isempty(i
->unit_file_state
))
3473 printf(" Loaded: %s%s%s (%s; %s)\n",
3474 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3476 printf(" Loaded: %s%s%s (%s)\n",
3477 on
, strna(i
->load_state
), off
, path
);
3479 printf(" Loaded: %s%s%s\n",
3480 on
, strna(i
->load_state
), off
);
3483 printf("Transient: yes\n");
3485 if (!strv_isempty(i
->dropin_paths
)) {
3486 _cleanup_free_
char *dir
= NULL
;
3490 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3491 if (! dir
|| last
) {
3492 printf(dir
? " " : " Drop-In: ");
3496 dir
= dirname_malloc(*dropin
);
3502 printf("%s\n %s", dir
,
3503 draw_special_char(DRAW_TREE_RIGHT
));
3506 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3508 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3512 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3514 printf(" Active: %s%s (%s)%s",
3515 active_on
, strna(i
->active_state
), ss
, active_off
);
3517 printf(" Active: %s%s%s",
3518 active_on
, strna(i
->active_state
), active_off
);
3520 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3521 printf(" (Result: %s)", i
->result
);
3523 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3524 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3525 (streq_ptr(i
->active_state
, "inactive") ||
3526 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3527 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3528 i
->active_exit_timestamp
;
3530 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3531 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3534 printf(" since %s; %s\n", s2
, s1
);
3536 printf(" since %s\n", s2
);
3540 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3541 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3542 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3544 printf("Condition: start %scondition failed%s at %s%s%s\n",
3545 ansi_highlight_yellow(), ansi_normal(),
3546 s2
, s1
? "; " : "", strempty(s1
));
3547 if (i
->failed_condition_trigger
)
3548 printf(" none of the trigger conditions were met\n");
3549 else if (i
->failed_condition
)
3550 printf(" %s=%s%s was not met\n",
3551 i
->failed_condition
,
3552 i
->failed_condition_negate
? "!" : "",
3553 i
->failed_condition_parameter
);
3556 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3557 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3558 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3560 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3561 ansi_highlight_red(), ansi_normal(),
3562 s2
, s1
? "; " : "", strempty(s1
));
3563 if (i
->failed_assert_trigger
)
3564 printf(" none of the trigger assertions were met\n");
3565 else if (i
->failed_assert
)
3566 printf(" %s=%s%s was not met\n",
3568 i
->failed_assert_negate
? "!" : "",
3569 i
->failed_assert_parameter
);
3573 printf(" Device: %s\n", i
->sysfs_path
);
3575 printf(" Where: %s\n", i
->where
);
3577 printf(" What: %s\n", i
->what
);
3579 STRV_FOREACH(t
, i
->documentation
)
3580 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3582 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3583 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3586 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3588 LIST_FOREACH(exec
, p
, i
->exec
) {
3589 _cleanup_free_
char *argv
= NULL
;
3592 /* Only show exited processes here */
3596 argv
= strv_join(p
->argv
, " ");
3597 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3599 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3601 on
= ansi_highlight_red();
3602 off
= ansi_normal();
3606 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3608 if (p
->code
== CLD_EXITED
) {
3611 printf("status=%i", p
->status
);
3613 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3618 printf("signal=%s", signal_to_string(p
->status
));
3620 printf(")%s\n", off
);
3622 if (i
->main_pid
== p
->pid
&&
3623 i
->start_timestamp
== p
->start_timestamp
&&
3624 i
->exit_timestamp
== p
->start_timestamp
)
3625 /* Let's not show this twice */
3628 if (p
->pid
== i
->control_pid
)
3632 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3633 if (i
->main_pid
> 0) {
3634 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3637 _cleanup_free_
char *comm
= NULL
;
3638 get_process_comm(i
->main_pid
, &comm
);
3640 printf(" (%s)", comm
);
3641 } else if (i
->exit_code
> 0) {
3642 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3644 if (i
->exit_code
== CLD_EXITED
) {
3647 printf("status=%i", i
->exit_status
);
3649 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3654 printf("signal=%s", signal_to_string(i
->exit_status
));
3658 if (i
->control_pid
> 0)
3662 if (i
->control_pid
> 0) {
3663 _cleanup_free_
char *c
= NULL
;
3665 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3667 get_process_comm(i
->control_pid
, &c
);
3676 printf(" Status: \"%s\"\n", i
->status_text
);
3677 if (i
->status_errno
> 0)
3678 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3680 if (i
->tasks_current
!= (uint64_t) -1) {
3681 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3683 if (i
->tasks_max
!= (uint64_t) -1)
3684 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3689 if (i
->memory_current
!= (uint64_t) -1) {
3690 char buf
[FORMAT_BYTES_MAX
];
3692 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3694 if (i
->memory_limit
!= (uint64_t) -1)
3695 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3700 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3701 char buf
[FORMAT_TIMESPAN_MAX
];
3702 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3705 if (i
->control_group
&&
3706 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3707 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3710 printf(" CGroup: %s\n", i
->control_group
);
3712 if (IN_SET(arg_transport
,
3713 BUS_TRANSPORT_LOCAL
,
3714 BUS_TRANSPORT_MACHINE
)) {
3717 static const char prefix
[] = " ";
3720 if (c
> sizeof(prefix
) - 1)
3721 c
-= sizeof(prefix
) - 1;
3725 if (i
->main_pid
> 0)
3726 extra
[k
++] = i
->main_pid
;
3728 if (i
->control_pid
> 0)
3729 extra
[k
++] = i
->control_pid
;
3731 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3735 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3736 show_journal_by_unit(
3741 i
->inactive_exit_timestamp_monotonic
,
3744 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3745 SD_JOURNAL_LOCAL_ONLY
,
3746 arg_scope
== UNIT_FILE_SYSTEM
,
3749 if (i
->need_daemon_reload
)
3750 warn_unit_file_changed(i
->id
);
3753 static void show_unit_help(UnitStatusInfo
*i
) {
3758 if (!i
->documentation
) {
3759 log_info("Documentation for %s not known.", i
->id
);
3763 STRV_FOREACH(p
, i
->documentation
)
3764 if (startswith(*p
, "man:"))
3765 show_man_page(*p
+ 4, false);
3767 log_info("Can't show: %s", *p
);
3770 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3777 switch (contents
[0]) {
3779 case SD_BUS_TYPE_STRING
: {
3782 r
= sd_bus_message_read(m
, "s", &s
);
3784 return bus_log_parse_error(r
);
3787 if (streq(name
, "Id"))
3789 else if (streq(name
, "LoadState"))
3791 else if (streq(name
, "ActiveState"))
3792 i
->active_state
= s
;
3793 else if (streq(name
, "SubState"))
3795 else if (streq(name
, "Description"))
3797 else if (streq(name
, "FragmentPath"))
3798 i
->fragment_path
= s
;
3799 else if (streq(name
, "SourcePath"))
3802 else if (streq(name
, "DefaultControlGroup")) {
3804 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3806 i
->control_group
= e
;
3809 else if (streq(name
, "ControlGroup"))
3810 i
->control_group
= s
;
3811 else if (streq(name
, "StatusText"))
3813 else if (streq(name
, "PIDFile"))
3815 else if (streq(name
, "SysFSPath"))
3817 else if (streq(name
, "Where"))
3819 else if (streq(name
, "What"))
3821 else if (streq(name
, "Following"))
3823 else if (streq(name
, "UnitFileState"))
3824 i
->unit_file_state
= s
;
3825 else if (streq(name
, "UnitFilePreset"))
3826 i
->unit_file_preset
= s
;
3827 else if (streq(name
, "Result"))
3834 case SD_BUS_TYPE_BOOLEAN
: {
3837 r
= sd_bus_message_read(m
, "b", &b
);
3839 return bus_log_parse_error(r
);
3841 if (streq(name
, "Accept"))
3843 else if (streq(name
, "NeedDaemonReload"))
3844 i
->need_daemon_reload
= b
;
3845 else if (streq(name
, "ConditionResult"))
3846 i
->condition_result
= b
;
3847 else if (streq(name
, "AssertResult"))
3848 i
->assert_result
= b
;
3849 else if (streq(name
, "Transient"))
3855 case SD_BUS_TYPE_UINT32
: {
3858 r
= sd_bus_message_read(m
, "u", &u
);
3860 return bus_log_parse_error(r
);
3862 if (streq(name
, "MainPID")) {
3864 i
->main_pid
= (pid_t
) u
;
3867 } else if (streq(name
, "ControlPID"))
3868 i
->control_pid
= (pid_t
) u
;
3869 else if (streq(name
, "ExecMainPID")) {
3871 i
->main_pid
= (pid_t
) u
;
3872 } else if (streq(name
, "NAccepted"))
3874 else if (streq(name
, "NConnections"))
3875 i
->n_connections
= u
;
3880 case SD_BUS_TYPE_INT32
: {
3883 r
= sd_bus_message_read(m
, "i", &j
);
3885 return bus_log_parse_error(r
);
3887 if (streq(name
, "ExecMainCode"))
3888 i
->exit_code
= (int) j
;
3889 else if (streq(name
, "ExecMainStatus"))
3890 i
->exit_status
= (int) j
;
3891 else if (streq(name
, "StatusErrno"))
3892 i
->status_errno
= (int) j
;
3897 case SD_BUS_TYPE_UINT64
: {
3900 r
= sd_bus_message_read(m
, "t", &u
);
3902 return bus_log_parse_error(r
);
3904 if (streq(name
, "ExecMainStartTimestamp"))
3905 i
->start_timestamp
= (usec_t
) u
;
3906 else if (streq(name
, "ExecMainExitTimestamp"))
3907 i
->exit_timestamp
= (usec_t
) u
;
3908 else if (streq(name
, "ActiveEnterTimestamp"))
3909 i
->active_enter_timestamp
= (usec_t
) u
;
3910 else if (streq(name
, "InactiveEnterTimestamp"))
3911 i
->inactive_enter_timestamp
= (usec_t
) u
;
3912 else if (streq(name
, "InactiveExitTimestamp"))
3913 i
->inactive_exit_timestamp
= (usec_t
) u
;
3914 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3915 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3916 else if (streq(name
, "ActiveExitTimestamp"))
3917 i
->active_exit_timestamp
= (usec_t
) u
;
3918 else if (streq(name
, "ConditionTimestamp"))
3919 i
->condition_timestamp
= (usec_t
) u
;
3920 else if (streq(name
, "AssertTimestamp"))
3921 i
->assert_timestamp
= (usec_t
) u
;
3922 else if (streq(name
, "MemoryCurrent"))
3923 i
->memory_current
= u
;
3924 else if (streq(name
, "MemoryLimit"))
3925 i
->memory_limit
= u
;
3926 else if (streq(name
, "TasksCurrent"))
3927 i
->tasks_current
= u
;
3928 else if (streq(name
, "TasksMax"))
3930 else if (streq(name
, "CPUUsageNSec"))
3931 i
->cpu_usage_nsec
= u
;
3936 case SD_BUS_TYPE_ARRAY
:
3938 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3939 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3941 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3943 return bus_log_parse_error(r
);
3945 info
= new0(ExecStatusInfo
, 1);
3949 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3951 info
->name
= strdup(name
);
3955 LIST_PREPEND(exec
, i
->exec
, info
);
3957 info
= new0(ExecStatusInfo
, 1);
3963 return bus_log_parse_error(r
);
3965 r
= sd_bus_message_exit_container(m
);
3967 return bus_log_parse_error(r
);
3971 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3972 const char *type
, *path
;
3974 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3976 return bus_log_parse_error(r
);
3978 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3980 r
= strv_extend(&i
->listen
, type
);
3984 r
= strv_extend(&i
->listen
, path
);
3989 return bus_log_parse_error(r
);
3991 r
= sd_bus_message_exit_container(m
);
3993 return bus_log_parse_error(r
);
3997 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3999 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4001 return bus_log_parse_error(r
);
4003 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4005 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4007 return bus_log_parse_error(r
);
4009 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4010 const char *cond
, *param
;
4011 int trigger
, negate
;
4014 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4016 return bus_log_parse_error(r
);
4018 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4019 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4020 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4021 i
->failed_condition
= cond
;
4022 i
->failed_condition_trigger
= trigger
;
4023 i
->failed_condition_negate
= negate
;
4024 i
->failed_condition_parameter
= param
;
4028 return bus_log_parse_error(r
);
4030 r
= sd_bus_message_exit_container(m
);
4032 return bus_log_parse_error(r
);
4034 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4035 const char *cond
, *param
;
4036 int trigger
, negate
;
4039 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4041 return bus_log_parse_error(r
);
4043 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4044 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4045 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4046 i
->failed_assert
= cond
;
4047 i
->failed_assert_trigger
= trigger
;
4048 i
->failed_assert_negate
= negate
;
4049 i
->failed_assert_parameter
= param
;
4053 return bus_log_parse_error(r
);
4055 r
= sd_bus_message_exit_container(m
);
4057 return bus_log_parse_error(r
);
4064 case SD_BUS_TYPE_STRUCT_BEGIN
:
4066 if (streq(name
, "LoadError")) {
4067 const char *n
, *message
;
4069 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4071 return bus_log_parse_error(r
);
4073 if (!isempty(message
))
4074 i
->load_error
= message
;
4087 r
= sd_bus_message_skip(m
, contents
);
4089 return bus_log_parse_error(r
);
4094 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4100 /* This is a low-level property printer, see
4101 * print_status_info() for the nicer output */
4103 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4104 /* skip what we didn't read */
4105 r
= sd_bus_message_skip(m
, contents
);
4109 switch (contents
[0]) {
4111 case SD_BUS_TYPE_STRUCT_BEGIN
:
4113 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4116 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4118 return bus_log_parse_error(r
);
4121 printf("%s=%"PRIu32
"\n", name
, u
);
4123 printf("%s=\n", name
);
4127 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4130 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4132 return bus_log_parse_error(r
);
4134 if (arg_all
|| !isempty(s
))
4135 printf("%s=%s\n", name
, s
);
4139 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4140 const char *a
= NULL
, *b
= NULL
;
4142 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4144 return bus_log_parse_error(r
);
4146 if (arg_all
|| !isempty(a
) || !isempty(b
))
4147 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4150 } else if (streq_ptr(name
, "SystemCallFilter")) {
4151 _cleanup_strv_free_
char **l
= NULL
;
4154 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4156 return bus_log_parse_error(r
);
4158 r
= sd_bus_message_read(m
, "b", &whitelist
);
4160 return bus_log_parse_error(r
);
4162 r
= sd_bus_message_read_strv(m
, &l
);
4164 return bus_log_parse_error(r
);
4166 r
= sd_bus_message_exit_container(m
);
4168 return bus_log_parse_error(r
);
4170 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4174 fputs(name
, stdout
);
4180 STRV_FOREACH(i
, l
) {
4188 fputc('\n', stdout
);
4196 case SD_BUS_TYPE_ARRAY
:
4198 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4202 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4204 return bus_log_parse_error(r
);
4206 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4207 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4210 return bus_log_parse_error(r
);
4212 r
= sd_bus_message_exit_container(m
);
4214 return bus_log_parse_error(r
);
4218 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4219 const char *type
, *path
;
4221 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4223 return bus_log_parse_error(r
);
4225 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4226 printf("%s=%s\n", type
, path
);
4228 return bus_log_parse_error(r
);
4230 r
= sd_bus_message_exit_container(m
);
4232 return bus_log_parse_error(r
);
4236 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4237 const char *type
, *path
;
4239 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4241 return bus_log_parse_error(r
);
4243 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4244 printf("Listen%s=%s\n", type
, path
);
4246 return bus_log_parse_error(r
);
4248 r
= sd_bus_message_exit_container(m
);
4250 return bus_log_parse_error(r
);
4254 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4256 uint64_t value
, next_elapse
;
4258 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4260 return bus_log_parse_error(r
);
4262 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4263 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4265 printf("%s={ value=%s ; next_elapse=%s }\n",
4267 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4268 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4271 return bus_log_parse_error(r
);
4273 r
= sd_bus_message_exit_container(m
);
4275 return bus_log_parse_error(r
);
4279 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4280 ExecStatusInfo info
= {};
4282 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4284 return bus_log_parse_error(r
);
4286 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4287 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4288 _cleanup_free_
char *tt
;
4290 tt
= strv_join(info
.argv
, " ");
4292 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",
4296 yes_no(info
.ignore
),
4297 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4298 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4300 sigchld_code_to_string(info
.code
),
4302 info
.code
== CLD_EXITED
? "" : "/",
4303 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4306 strv_free(info
.argv
);
4310 r
= sd_bus_message_exit_container(m
);
4312 return bus_log_parse_error(r
);
4316 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4317 const char *path
, *rwm
;
4319 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4321 return bus_log_parse_error(r
);
4323 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4324 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4326 return bus_log_parse_error(r
);
4328 r
= sd_bus_message_exit_container(m
);
4330 return bus_log_parse_error(r
);
4334 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4338 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4340 return bus_log_parse_error(r
);
4342 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4343 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4345 return bus_log_parse_error(r
);
4347 r
= sd_bus_message_exit_container(m
);
4349 return bus_log_parse_error(r
);
4353 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4357 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4359 return bus_log_parse_error(r
);
4361 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4362 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4364 return bus_log_parse_error(r
);
4366 r
= sd_bus_message_exit_container(m
);
4368 return bus_log_parse_error(r
);
4376 r
= bus_print_property(name
, m
, arg_all
);
4378 return bus_log_parse_error(r
);
4381 r
= sd_bus_message_skip(m
, contents
);
4383 return bus_log_parse_error(r
);
4386 printf("%s=[unprintable]\n", name
);
4392 static int show_one(
4396 bool show_properties
,
4400 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4401 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4402 UnitStatusInfo info
= {
4403 .memory_current
= (uint64_t) -1,
4404 .memory_limit
= (uint64_t) -1,
4405 .cpu_usage_nsec
= (uint64_t) -1,
4406 .tasks_current
= (uint64_t) -1,
4407 .tasks_max
= (uint64_t) -1,
4415 log_debug("Showing one %s", path
);
4417 r
= sd_bus_call_method(
4419 "org.freedesktop.systemd1",
4421 "org.freedesktop.DBus.Properties",
4427 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4429 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4431 return bus_log_parse_error(r
);
4438 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4439 const char *name
, *contents
;
4441 r
= sd_bus_message_read(reply
, "s", &name
);
4443 return bus_log_parse_error(r
);
4445 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4447 return bus_log_parse_error(r
);
4449 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4451 return bus_log_parse_error(r
);
4453 if (show_properties
)
4454 r
= print_property(name
, reply
, contents
);
4456 r
= status_property(name
, reply
, &info
, contents
);
4460 r
= sd_bus_message_exit_container(reply
);
4462 return bus_log_parse_error(r
);
4464 r
= sd_bus_message_exit_container(reply
);
4466 return bus_log_parse_error(r
);
4469 return bus_log_parse_error(r
);
4471 r
= sd_bus_message_exit_container(reply
);
4473 return bus_log_parse_error(r
);
4477 if (!show_properties
) {
4478 if (streq(verb
, "help"))
4479 show_unit_help(&info
);
4481 print_status_info(&info
, ellipsized
);
4484 strv_free(info
.documentation
);
4485 strv_free(info
.dropin_paths
);
4486 strv_free(info
.listen
);
4488 if (!streq_ptr(info
.active_state
, "active") &&
4489 !streq_ptr(info
.active_state
, "reloading") &&
4490 streq(verb
, "status")) {
4491 /* According to LSB: "program not running" */
4492 /* 0: program is running or service is OK
4493 * 1: program is dead and /run PID file exists
4494 * 2: program is dead and /run/lock lock file exists
4495 * 3: program is not running
4496 * 4: program or service status is unknown
4498 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4504 while ((p
= info
.exec
)) {
4505 LIST_REMOVE(exec
, info
.exec
, p
);
4506 exec_status_info_free(p
);
4512 static int get_unit_dbus_path_by_pid(
4517 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4518 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4522 r
= sd_bus_call_method(
4524 "org.freedesktop.systemd1",
4525 "/org/freedesktop/systemd1",
4526 "org.freedesktop.systemd1.Manager",
4532 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4534 r
= sd_bus_message_read(reply
, "o", &u
);
4536 return bus_log_parse_error(r
);
4546 static int show_all(
4549 bool show_properties
,
4553 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4554 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4559 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4563 pager_open_if_enabled();
4567 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4569 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4570 _cleanup_free_
char *p
= NULL
;
4572 p
= unit_dbus_path_from_name(u
->id
);
4576 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4579 else if (r
> 0 && ret
== 0)
4586 static int show_system_status(sd_bus
*bus
) {
4587 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4588 _cleanup_free_
char *hn
= NULL
;
4589 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4590 const char *on
, *off
;
4593 hn
= gethostname_malloc();
4597 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4599 return log_error_errno(r
, "Failed to read server status: %m");
4601 if (streq_ptr(mi
.state
, "degraded")) {
4602 on
= ansi_highlight_red();
4603 off
= ansi_normal();
4604 } else if (!streq_ptr(mi
.state
, "running")) {
4605 on
= ansi_highlight_yellow();
4606 off
= ansi_normal();
4610 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4612 printf(" State: %s%s%s\n",
4613 on
, strna(mi
.state
), off
);
4615 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4616 printf(" Failed: %u units\n", mi
.n_failed_units
);
4618 printf(" Since: %s; %s\n",
4619 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4620 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4622 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4623 if (IN_SET(arg_transport
,
4624 BUS_TRANSPORT_LOCAL
,
4625 BUS_TRANSPORT_MACHINE
)) {
4626 static const char prefix
[] = " ";
4630 if (c
> sizeof(prefix
) - 1)
4631 c
-= sizeof(prefix
) - 1;
4635 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4641 static int show(int argc
, char *argv
[], void *userdata
) {
4642 bool show_properties
, show_status
, show_help
, new_line
= false;
4643 bool ellipsized
= false;
4649 show_properties
= streq(argv
[0], "show");
4650 show_status
= streq(argv
[0], "status");
4651 show_help
= streq(argv
[0], "help");
4653 if (show_help
&& argc
<= 1) {
4654 log_error("This command expects one or more unit names. Did you mean --help?");
4658 pager_open_if_enabled();
4661 /* Increase max number of open files to 16K if we can, we
4662 * might needs this when browsing journal files, which might
4663 * be split up into many files. */
4664 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4666 r
= acquire_bus(BUS_MANAGER
, &bus
);
4670 /* If no argument is specified inspect the manager itself */
4671 if (show_properties
&& argc
<= 1)
4672 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4674 if (show_status
&& argc
<= 1) {
4676 pager_open_if_enabled();
4677 show_system_status(bus
);
4681 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4683 _cleanup_free_
char **patterns
= NULL
;
4686 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4687 _cleanup_free_
char *unit
= NULL
;
4690 if (safe_atou32(*name
, &id
) < 0) {
4691 if (strv_push(&patterns
, *name
) < 0)
4695 } else if (show_properties
) {
4696 /* Interpret as job id */
4697 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4701 /* Interpret as PID */
4702 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4709 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4712 else if (r
> 0 && ret
== 0)
4716 if (!strv_isempty(patterns
)) {
4717 _cleanup_strv_free_
char **names
= NULL
;
4719 r
= expand_names(bus
, patterns
, NULL
, &names
);
4721 return log_error_errno(r
, "Failed to expand names: %m");
4723 STRV_FOREACH(name
, names
) {
4724 _cleanup_free_
char *unit
;
4726 unit
= unit_dbus_path_from_name(*name
);
4730 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4733 else if (r
> 0 && ret
== 0)
4739 if (ellipsized
&& !arg_quiet
)
4740 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4745 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4749 assert(user_runtime
);
4752 if (arg_scope
== UNIT_FILE_USER
) {
4753 r
= user_config_home(user_home
);
4755 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4757 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4759 r
= user_runtime_dir(user_runtime
);
4761 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4763 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4766 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4768 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4773 static int cat_file(const char *filename
, bool newline
) {
4774 _cleanup_close_
int fd
;
4776 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4780 printf("%s%s# %s%s\n",
4781 newline
? "\n" : "",
4782 ansi_highlight_blue(),
4787 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4790 static int cat(int argc
, char *argv
[], void *userdata
) {
4791 _cleanup_free_
char *user_home
= NULL
;
4792 _cleanup_free_
char *user_runtime
= NULL
;
4793 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4794 _cleanup_strv_free_
char **names
= NULL
;
4800 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4801 log_error("Cannot remotely cat units.");
4805 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4809 r
= acquire_bus(BUS_MANAGER
, &bus
);
4813 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4815 return log_error_errno(r
, "Failed to expand names: %m");
4817 pager_open_if_enabled();
4819 STRV_FOREACH(name
, names
) {
4820 _cleanup_free_
char *fragment_path
= NULL
;
4821 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4824 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4835 if (fragment_path
) {
4836 r
= cat_file(fragment_path
, false);
4838 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4841 STRV_FOREACH(path
, dropin_paths
) {
4842 r
= cat_file(*path
, path
== dropin_paths
);
4844 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4851 static int set_property(int argc
, char *argv
[], void *userdata
) {
4852 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4853 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4854 _cleanup_free_
char *n
= NULL
;
4859 polkit_agent_open_if_enabled();
4861 r
= acquire_bus(BUS_MANAGER
, &bus
);
4865 r
= sd_bus_message_new_method_call(
4868 "org.freedesktop.systemd1",
4869 "/org/freedesktop/systemd1",
4870 "org.freedesktop.systemd1.Manager",
4871 "SetUnitProperties");
4873 return bus_log_create_error(r
);
4875 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4877 return log_error_errno(r
, "Failed to mangle unit name: %m");
4879 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4881 return bus_log_create_error(r
);
4883 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4885 return bus_log_create_error(r
);
4887 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4888 r
= bus_append_unit_property_assignment(m
, *i
);
4893 r
= sd_bus_message_close_container(m
);
4895 return bus_log_create_error(r
);
4897 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4899 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4904 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4905 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4910 polkit_agent_open_if_enabled();
4912 r
= acquire_bus(BUS_MANAGER
, &bus
);
4916 if (arg_action
== ACTION_RELOAD
)
4918 else if (arg_action
== ACTION_REEXEC
)
4919 method
= "Reexecute";
4921 assert(arg_action
== ACTION_SYSTEMCTL
);
4924 streq(argv
[0], "clear-jobs") ||
4925 streq(argv
[0], "cancel") ? "ClearJobs" :
4926 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4927 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4928 streq(argv
[0], "halt") ? "Halt" :
4929 streq(argv
[0], "poweroff") ? "PowerOff" :
4930 streq(argv
[0], "reboot") ? "Reboot" :
4931 streq(argv
[0], "kexec") ? "KExec" :
4932 streq(argv
[0], "exit") ? "Exit" :
4933 /* "daemon-reload" */ "Reload";
4936 r
= sd_bus_call_method(
4938 "org.freedesktop.systemd1",
4939 "/org/freedesktop/systemd1",
4940 "org.freedesktop.systemd1.Manager",
4945 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4946 /* There's always a fallback possible for
4947 * legacy actions. */
4949 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4950 /* On reexecution, we expect a disconnect, not a
4954 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
4956 return r
< 0 ? r
: 0;
4959 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4960 _cleanup_strv_free_
char **names
= NULL
;
4966 return daemon_reload(argc
, argv
, userdata
);
4968 polkit_agent_open_if_enabled();
4970 r
= acquire_bus(BUS_MANAGER
, &bus
);
4974 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4976 return log_error_errno(r
, "Failed to expand names: %m");
4978 STRV_FOREACH(name
, names
) {
4979 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4981 q
= sd_bus_call_method(
4983 "org.freedesktop.systemd1",
4984 "/org/freedesktop/systemd1",
4985 "org.freedesktop.systemd1.Manager",
4991 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5000 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5001 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5002 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5007 pager_open_if_enabled();
5009 r
= acquire_bus(BUS_MANAGER
, &bus
);
5013 r
= sd_bus_get_property(
5015 "org.freedesktop.systemd1",
5016 "/org/freedesktop/systemd1",
5017 "org.freedesktop.systemd1.Manager",
5023 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5025 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5027 return bus_log_parse_error(r
);
5029 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5032 return bus_log_parse_error(r
);
5034 r
= sd_bus_message_exit_container(reply
);
5036 return bus_log_parse_error(r
);
5041 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5042 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5043 _cleanup_free_
char *cmdline_init
= NULL
;
5044 const char *root
, *init
;
5048 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5049 log_error("Cannot switch root remotely.");
5053 if (argc
< 2 || argc
> 3) {
5054 log_error("Wrong number of arguments.");
5063 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5064 "init", &cmdline_init
,
5067 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5069 init
= cmdline_init
;
5076 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5078 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5079 root_init_path
= strjoina(root
, "/", init
);
5081 /* If the passed init is actually the same as the
5082 * systemd binary, then let's suppress it. */
5083 if (files_same(root_init_path
, root_systemd_path
) > 0)
5087 r
= acquire_bus(BUS_MANAGER
, &bus
);
5091 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5093 r
= sd_bus_call_method(
5095 "org.freedesktop.systemd1",
5096 "/org/freedesktop/systemd1",
5097 "org.freedesktop.systemd1.Manager",
5103 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5108 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5109 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5110 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5118 polkit_agent_open_if_enabled();
5120 r
= acquire_bus(BUS_MANAGER
, &bus
);
5124 method
= streq(argv
[0], "set-environment")
5126 : "UnsetEnvironment";
5128 r
= sd_bus_message_new_method_call(
5131 "org.freedesktop.systemd1",
5132 "/org/freedesktop/systemd1",
5133 "org.freedesktop.systemd1.Manager",
5136 return bus_log_create_error(r
);
5138 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5140 return bus_log_create_error(r
);
5142 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5144 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5149 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5150 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5151 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5155 polkit_agent_open_if_enabled();
5157 r
= acquire_bus(BUS_MANAGER
, &bus
);
5161 r
= sd_bus_message_new_method_call(
5164 "org.freedesktop.systemd1",
5165 "/org/freedesktop/systemd1",
5166 "org.freedesktop.systemd1.Manager",
5169 return bus_log_create_error(r
);
5172 r
= sd_bus_message_append_strv(m
, environ
);
5176 r
= sd_bus_message_open_container(m
, 'a', "s");
5178 return bus_log_create_error(r
);
5180 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5182 if (!env_name_is_valid(*a
)) {
5183 log_error("Not a valid environment variable name: %s", *a
);
5187 STRV_FOREACH(b
, environ
) {
5190 eq
= startswith(*b
, *a
);
5191 if (eq
&& *eq
== '=') {
5193 r
= sd_bus_message_append(m
, "s", *b
);
5195 return bus_log_create_error(r
);
5202 r
= sd_bus_message_close_container(m
);
5205 return bus_log_create_error(r
);
5207 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5209 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5214 static int enable_sysv_units(const char *verb
, char **args
) {
5217 #if defined(HAVE_SYSV_COMPAT)
5219 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5221 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5224 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5227 if (!STR_IN_SET(verb
,
5233 /* Processes all SysV units, and reshuffles the array so that
5234 * afterwards only the native units remain */
5236 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5243 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5244 bool found_native
= false, found_sysv
;
5246 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5254 if (!endswith(name
, ".service"))
5257 if (path_is_absolute(name
))
5260 STRV_FOREACH(k
, paths
.unit_path
) {
5261 _cleanup_free_
char *path
= NULL
;
5263 path
= path_join(arg_root
, *k
, name
);
5267 found_native
= access(path
, F_OK
) >= 0;
5272 /* If we have both a native unit and a SysV script,
5273 * enable/disable them both (below); for is-enabled, prefer the
5275 if (found_native
&& streq(verb
, "is-enabled"))
5278 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5282 p
[strlen(p
) - strlen(".service")] = 0;
5283 found_sysv
= access(p
, F_OK
) >= 0;
5288 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5290 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5292 if (!isempty(arg_root
))
5293 argv
[c
++] = q
= strappend("--root=", arg_root
);
5296 argv
[c
++] = basename(p
);
5299 l
= strv_join((char**)argv
, " ");
5303 log_info("Executing %s", l
);
5307 return log_error_errno(errno
, "Failed to fork: %m");
5308 else if (pid
== 0) {
5311 (void) reset_all_signal_handlers();
5312 (void) reset_signal_mask();
5314 execv(argv
[0], (char**) argv
);
5315 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5316 _exit(EXIT_FAILURE
);
5319 j
= wait_for_terminate(pid
, &status
);
5321 log_error_errno(j
, "Failed to wait for child: %m");
5325 if (status
.si_code
== CLD_EXITED
) {
5326 if (streq(verb
, "is-enabled")) {
5327 if (status
.si_status
== 0) {
5336 } else if (status
.si_status
!= 0)
5344 /* Remove this entry, so that we don't try enabling it as native unit */
5347 assert(args
[f
] == name
);
5348 strv_remove(args
, name
);
5355 static int mangle_names(char **original_names
, char ***mangled_names
) {
5356 char **i
, **l
, **name
;
5359 l
= i
= new(char*, strv_length(original_names
) + 1);
5363 STRV_FOREACH(name
, original_names
) {
5365 /* When enabling units qualified path names are OK,
5366 * too, hence allow them explicitly. */
5368 if (is_path(*name
)) {
5375 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5378 return log_error_errno(r
, "Failed to mangle unit name: %m");
5391 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5392 _cleanup_strv_free_
char **names
= NULL
;
5393 const char *verb
= argv
[0];
5394 UnitFileChange
*changes
= NULL
;
5395 unsigned n_changes
= 0;
5396 int carries_install_info
= -1;
5402 r
= mangle_names(strv_skip(argv
, 1), &names
);
5406 r
= enable_sysv_units(verb
, names
);
5410 /* If the operation was fully executed by the SysV compat,
5411 * let's finish early */
5412 if (strv_isempty(names
))
5415 if (install_client_side()) {
5416 if (streq(verb
, "enable")) {
5417 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5418 carries_install_info
= r
;
5419 } else if (streq(verb
, "disable"))
5420 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5421 else if (streq(verb
, "reenable")) {
5422 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5423 carries_install_info
= r
;
5424 } else if (streq(verb
, "link"))
5425 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5426 else if (streq(verb
, "preset")) {
5427 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5428 carries_install_info
= r
;
5429 } else if (streq(verb
, "mask"))
5430 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5431 else if (streq(verb
, "unmask"))
5432 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5434 assert_not_reached("Unknown verb");
5436 if (r
== -ESHUTDOWN
)
5437 return log_error_errno(r
, "Unit file is masked.");
5439 return log_error_errno(r
, "Operation failed: %m");
5442 dump_unit_file_changes(changes
, n_changes
);
5446 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5447 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5448 int expect_carries_install_info
= false;
5449 bool send_force
= true, send_preset_mode
= false;
5453 polkit_agent_open_if_enabled();
5455 r
= acquire_bus(BUS_MANAGER
, &bus
);
5459 if (streq(verb
, "enable")) {
5460 method
= "EnableUnitFiles";
5461 expect_carries_install_info
= true;
5462 } else if (streq(verb
, "disable")) {
5463 method
= "DisableUnitFiles";
5465 } else if (streq(verb
, "reenable")) {
5466 method
= "ReenableUnitFiles";
5467 expect_carries_install_info
= true;
5468 } else if (streq(verb
, "link"))
5469 method
= "LinkUnitFiles";
5470 else if (streq(verb
, "preset")) {
5472 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5473 method
= "PresetUnitFilesWithMode";
5474 send_preset_mode
= true;
5476 method
= "PresetUnitFiles";
5478 expect_carries_install_info
= true;
5479 } else if (streq(verb
, "mask"))
5480 method
= "MaskUnitFiles";
5481 else if (streq(verb
, "unmask")) {
5482 method
= "UnmaskUnitFiles";
5485 assert_not_reached("Unknown verb");
5487 r
= sd_bus_message_new_method_call(
5490 "org.freedesktop.systemd1",
5491 "/org/freedesktop/systemd1",
5492 "org.freedesktop.systemd1.Manager",
5495 return bus_log_create_error(r
);
5497 r
= sd_bus_message_append_strv(m
, names
);
5499 return bus_log_create_error(r
);
5501 if (send_preset_mode
) {
5502 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5504 return bus_log_create_error(r
);
5507 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5509 return bus_log_create_error(r
);
5512 r
= sd_bus_message_append(m
, "b", arg_force
);
5514 return bus_log_create_error(r
);
5517 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5519 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5521 if (expect_carries_install_info
) {
5522 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5524 return bus_log_parse_error(r
);
5527 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5531 /* Try to reload if enabled */
5533 r
= daemon_reload(argc
, argv
, userdata
);
5538 if (carries_install_info
== 0)
5539 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5540 "using systemctl.\n"
5541 "Possible reasons for having this kind of units are:\n"
5542 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5543 " .wants/ or .requires/ directory.\n"
5544 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5545 " a requirement dependency on it.\n"
5546 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5547 " D-Bus, udev, scripted systemctl call, ...).\n");
5549 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5550 char *new_args
[n_changes
+ 2];
5554 r
= acquire_bus(BUS_MANAGER
, &bus
);
5558 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5559 for (i
= 0; i
< n_changes
; i
++)
5560 new_args
[i
+ 1] = basename(changes
[i
].path
);
5561 new_args
[i
+ 1] = NULL
;
5563 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5567 unit_file_changes_free(changes
, n_changes
);
5572 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5573 _cleanup_strv_free_
char **names
= NULL
;
5574 _cleanup_free_
char *target
= NULL
;
5575 const char *verb
= argv
[0];
5582 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5584 return log_error_errno(r
, "Failed to mangle unit name: %m");
5586 r
= mangle_names(strv_skip(argv
, 2), &names
);
5590 if (streq(verb
, "add-wants"))
5592 else if (streq(verb
, "add-requires"))
5593 dep
= UNIT_REQUIRES
;
5595 assert_not_reached("Unknown verb");
5597 if (install_client_side()) {
5598 UnitFileChange
*changes
= NULL
;
5599 unsigned n_changes
= 0;
5601 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5602 if (r
== -ESHUTDOWN
)
5603 return log_error_errno(r
, "Unit file is masked.");
5605 return log_error_errno(r
, "Can't add dependency: %m");
5608 dump_unit_file_changes(changes
, n_changes
);
5610 unit_file_changes_free(changes
, n_changes
);
5613 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5614 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5617 polkit_agent_open_if_enabled();
5619 r
= acquire_bus(BUS_MANAGER
, &bus
);
5623 r
= sd_bus_message_new_method_call(
5626 "org.freedesktop.systemd1",
5627 "/org/freedesktop/systemd1",
5628 "org.freedesktop.systemd1.Manager",
5629 "AddDependencyUnitFiles");
5631 return bus_log_create_error(r
);
5633 r
= sd_bus_message_append_strv(m
, names
);
5635 return bus_log_create_error(r
);
5637 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5639 return bus_log_create_error(r
);
5641 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5643 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5645 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5650 r
= daemon_reload(argc
, argv
, userdata
);
5658 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5659 UnitFileChange
*changes
= NULL
;
5660 unsigned n_changes
= 0;
5663 if (install_client_side()) {
5665 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5667 log_error_errno(r
, "Operation failed: %m");
5672 dump_unit_file_changes(changes
, n_changes
);
5677 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5678 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5681 polkit_agent_open_if_enabled();
5683 r
= acquire_bus(BUS_MANAGER
, &bus
);
5687 r
= sd_bus_call_method(
5689 "org.freedesktop.systemd1",
5690 "/org/freedesktop/systemd1",
5691 "org.freedesktop.systemd1.Manager",
5692 "PresetAllUnitFiles",
5696 unit_file_preset_mode_to_string(arg_preset_mode
),
5700 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5702 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5707 r
= daemon_reload(argc
, argv
, userdata
);
5713 unit_file_changes_free(changes
, n_changes
);
5718 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5720 _cleanup_strv_free_
char **names
= NULL
;
5725 r
= mangle_names(strv_skip(argv
, 1), &names
);
5729 r
= enable_sysv_units(argv
[0], names
);
5735 if (install_client_side()) {
5737 STRV_FOREACH(name
, names
) {
5738 UnitFileState state
;
5740 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5742 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5746 UNIT_FILE_ENABLED_RUNTIME
,
5748 UNIT_FILE_INDIRECT
))
5752 puts(unit_file_state_to_string(state
));
5756 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5759 r
= acquire_bus(BUS_MANAGER
, &bus
);
5763 STRV_FOREACH(name
, names
) {
5764 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5767 r
= sd_bus_call_method(
5769 "org.freedesktop.systemd1",
5770 "/org/freedesktop/systemd1",
5771 "org.freedesktop.systemd1.Manager",
5777 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5779 r
= sd_bus_message_read(reply
, "s", &s
);
5781 return bus_log_parse_error(r
);
5783 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5794 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5795 _cleanup_free_
char *state
= NULL
;
5799 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5802 return EXIT_FAILURE
;
5805 r
= acquire_bus(BUS_MANAGER
, &bus
);
5809 r
= sd_bus_get_property_string(
5811 "org.freedesktop.systemd1",
5812 "/org/freedesktop/systemd1",
5813 "org.freedesktop.systemd1.Manager",
5826 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5829 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5830 _cleanup_free_
char *t
= NULL
;
5834 assert(original_path
);
5837 r
= tempfn_random(new_path
, NULL
, &t
);
5839 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5841 r
= mkdir_parents(new_path
, 0755);
5843 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5845 r
= copy_file(original_path
, t
, 0, 0644, 0);
5850 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5853 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5861 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5862 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5867 switch (arg_scope
) {
5868 case UNIT_FILE_SYSTEM
:
5869 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5871 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5873 case UNIT_FILE_GLOBAL
:
5874 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5876 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5878 case UNIT_FILE_USER
:
5880 assert(user_runtime
);
5882 path
= path_join(arg_root
, user_home
, name
);
5884 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5887 run
= path_join(arg_root
, user_runtime
, name
);
5891 assert_not_reached("Invalid scope");
5893 if (!path
|| (arg_runtime
&& !run
))
5897 if (access(path
, F_OK
) >= 0) {
5898 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5902 if (path2
&& access(path2
, F_OK
) >= 0) {
5903 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5917 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
) {
5918 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5922 assert(ret_new_path
);
5923 assert(ret_tmp_path
);
5925 ending
= strjoina(unit_name
, ".d/override.conf");
5926 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5930 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5936 *ret_new_path
= tmp_new_path
;
5937 *ret_tmp_path
= tmp_tmp_path
;
5942 static int unit_file_create_copy(
5943 const char *unit_name
,
5944 const char *fragment_path
,
5945 const char *user_home
,
5946 const char *user_runtime
,
5947 char **ret_new_path
,
5948 char **ret_tmp_path
) {
5950 char *tmp_new_path
, *tmp_tmp_path
;
5953 assert(fragment_path
);
5955 assert(ret_new_path
);
5956 assert(ret_tmp_path
);
5958 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5962 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5965 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5970 if (response
!= 'y') {
5971 log_warning("%s ignored", unit_name
);
5977 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5979 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5984 *ret_new_path
= tmp_new_path
;
5985 *ret_tmp_path
= tmp_tmp_path
;
5990 static int run_editor(char **paths
) {
5998 return log_error_errno(errno
, "Failed to fork: %m");
6002 char *editor
, **editor_args
= NULL
;
6003 char **tmp_path
, **original_path
, *p
;
6004 unsigned n_editor_args
= 0, i
= 1;
6007 (void) reset_all_signal_handlers();
6008 (void) reset_signal_mask();
6010 argc
= strv_length(paths
)/2 + 1;
6012 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6013 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6014 * we try to execute well known editors
6016 editor
= getenv("SYSTEMD_EDITOR");
6018 editor
= getenv("EDITOR");
6020 editor
= getenv("VISUAL");
6022 if (!isempty(editor
)) {
6023 editor_args
= strv_split(editor
, WHITESPACE
);
6026 _exit(EXIT_FAILURE
);
6028 n_editor_args
= strv_length(editor_args
);
6029 argc
+= n_editor_args
- 1;
6031 args
= newa(const char*, argc
+ 1);
6033 if (n_editor_args
> 0) {
6034 args
[0] = editor_args
[0];
6035 for (; i
< n_editor_args
; i
++)
6036 args
[i
] = editor_args
[i
];
6039 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6040 args
[i
] = *tmp_path
;
6045 if (n_editor_args
> 0)
6046 execvp(args
[0], (char* const*) args
);
6048 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6050 execvp(p
, (char* const*) args
);
6051 /* We do not fail if the editor doesn't exist
6052 * because we want to try each one of them before
6055 if (errno
!= ENOENT
) {
6056 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6057 _exit(EXIT_FAILURE
);
6061 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6062 _exit(EXIT_FAILURE
);
6065 r
= wait_for_terminate_and_warn("editor", pid
, true);
6067 return log_error_errno(r
, "Failed to wait for child: %m");
6072 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6073 _cleanup_free_
char *user_home
= NULL
;
6074 _cleanup_free_
char *user_runtime
= NULL
;
6075 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6082 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6086 STRV_FOREACH(name
, names
) {
6087 _cleanup_free_
char *path
= NULL
;
6088 char *new_path
, *tmp_path
;
6090 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6096 // FIXME: support units with path==NULL (no FragmentPath)
6097 log_error("No fragment exists for %s.", *name
);
6102 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6104 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6108 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6116 static int edit(int argc
, char *argv
[], void *userdata
) {
6117 _cleanup_strv_free_
char **names
= NULL
;
6118 _cleanup_strv_free_
char **paths
= NULL
;
6119 char **original
, **tmp
;
6124 log_error("Cannot edit units if not on a tty.");
6128 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6129 log_error("Cannot edit units remotely.");
6133 r
= acquire_bus(BUS_MANAGER
, &bus
);
6137 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6139 return log_error_errno(r
, "Failed to expand names: %m");
6141 r
= find_paths_to_edit(bus
, names
, &paths
);
6145 if (strv_isempty(paths
))
6148 r
= run_editor(paths
);
6152 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6153 /* If the temporary file is empty we ignore it. It's
6154 * useful if the user wants to cancel its modification
6156 if (null_or_empty_path(*tmp
)) {
6157 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6161 r
= rename(*tmp
, *original
);
6163 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6170 if (!arg_no_reload
&& !install_client_side())
6171 r
= daemon_reload(argc
, argv
, userdata
);
6174 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6175 (void) unlink(*tmp
);
6180 static void systemctl_help(void) {
6182 pager_open_if_enabled();
6184 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6185 "Query or send control commands to the systemd manager.\n\n"
6186 " -h --help Show this help\n"
6187 " --version Show package version\n"
6188 " --system Connect to system manager\n"
6189 " --user Connect to user service manager\n"
6190 " -H --host=[USER@]HOST\n"
6191 " Operate on remote host\n"
6192 " -M --machine=CONTAINER\n"
6193 " Operate on local container\n"
6194 " -t --type=TYPE List units of a particular type\n"
6195 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6196 " -p --property=NAME Show only properties by this name\n"
6197 " -a --all Show all loaded units/properties, including dead/empty\n"
6198 " ones. To list all units installed on the system, use\n"
6199 " the 'list-unit-files' command instead.\n"
6200 " -l --full Don't ellipsize unit names on output\n"
6201 " -r --recursive Show unit list of host and local containers\n"
6202 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6203 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6204 " queueing a new job\n"
6205 " --show-types When showing sockets, explicitly show their type\n"
6206 " -i --ignore-inhibitors\n"
6207 " When shutting down or sleeping, ignore inhibitors\n"
6208 " --kill-who=WHO Who to send signal to\n"
6209 " -s --signal=SIGNAL Which signal to send\n"
6210 " --now Start or stop unit in addition to enabling or disabling it\n"
6211 " -q --quiet Suppress output\n"
6212 " --no-block Do not wait until operation finished\n"
6213 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6214 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6215 " --no-legend Do not print a legend (column headers and hints)\n"
6216 " --no-pager Do not pipe output into a pager\n"
6217 " --no-ask-password\n"
6218 " Do not ask for system passwords\n"
6219 " --global Enable/disable unit files globally\n"
6220 " --runtime Enable unit files only temporarily until next reboot\n"
6221 " -f --force When enabling unit files, override existing symlinks\n"
6222 " When shutting down, execute action immediately\n"
6223 " --preset-mode= Apply only enable, only disable, or all presets\n"
6224 " --root=PATH Enable unit files in the specified root directory\n"
6225 " -n --lines=INTEGER Number of journal entries to show\n"
6226 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6227 " short-precise, short-monotonic, verbose,\n"
6228 " export, json, json-pretty, json-sse, cat)\n"
6229 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6230 " --plain Print unit dependencies as a list instead of a tree\n\n"
6232 " list-units [PATTERN...] List loaded units\n"
6233 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6234 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6235 " start NAME... Start (activate) one or more units\n"
6236 " stop NAME... Stop (deactivate) one or more units\n"
6237 " reload NAME... Reload one or more units\n"
6238 " restart NAME... Start or restart one or more units\n"
6239 " try-restart NAME... Restart one or more units if active\n"
6240 " reload-or-restart NAME... Reload one or more units if possible,\n"
6241 " otherwise start or restart\n"
6242 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6243 " if supported, otherwise restart\n"
6244 " isolate NAME Start one unit and stop all others\n"
6245 " kill NAME... Send signal to processes of a unit\n"
6246 " is-active PATTERN... Check whether units are active\n"
6247 " is-failed PATTERN... Check whether units are failed\n"
6248 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6249 " show [PATTERN...|JOB...] Show properties of one or more\n"
6250 " units/jobs or the manager\n"
6251 " cat PATTERN... Show files and drop-ins of one or more units\n"
6252 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6253 " help PATTERN...|PID... Show manual for one or more units\n"
6254 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6256 " list-dependencies [NAME] Recursively show units which are required\n"
6257 " or wanted by this unit or by which this\n"
6258 " unit is required or wanted\n\n"
6259 "Unit File Commands:\n"
6260 " list-unit-files [PATTERN...] List installed unit files\n"
6261 " enable NAME... Enable one or more unit files\n"
6262 " disable NAME... Disable one or more unit files\n"
6263 " reenable NAME... Reenable one or more unit files\n"
6264 " preset NAME... Enable/disable one or more unit files\n"
6265 " based on preset configuration\n"
6266 " preset-all Enable/disable all unit files based on\n"
6267 " preset configuration\n"
6268 " is-enabled NAME... Check whether unit files are enabled\n"
6269 " mask NAME... Mask one or more units\n"
6270 " unmask NAME... Unmask one or more units\n"
6271 " link PATH... Link one or more units files into\n"
6272 " the search path\n"
6273 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6274 " on specified one or more units\n"
6275 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6276 " on specified one or more units\n"
6277 " edit NAME... Edit one or more unit files\n"
6278 " get-default Get the name of the default target\n"
6279 " set-default NAME Set the default target\n\n"
6280 "Machine Commands:\n"
6281 " list-machines [PATTERN...] List local containers and host\n\n"
6283 " list-jobs [PATTERN...] List jobs\n"
6284 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6285 "Environment Commands:\n"
6286 " show-environment Dump environment\n"
6287 " set-environment NAME=VALUE... Set one or more environment variables\n"
6288 " unset-environment NAME... Unset one or more environment variables\n"
6289 " import-environment [NAME...] Import all or some environment variables\n\n"
6290 "Manager Lifecycle Commands:\n"
6291 " daemon-reload Reload systemd manager configuration\n"
6292 " daemon-reexec Reexecute systemd manager\n\n"
6293 "System Commands:\n"
6294 " is-system-running Check whether system is fully running\n"
6295 " default Enter system default mode\n"
6296 " rescue Enter system rescue mode\n"
6297 " emergency Enter system emergency mode\n"
6298 " halt Shut down and halt the system\n"
6299 " poweroff Shut down and power-off the system\n"
6300 " reboot [ARG] Shut down and reboot the system\n"
6301 " kexec Shut down and reboot the system with kexec\n"
6302 " exit [EXIT_CODE] Request user instance or container exit\n"
6303 " switch-root ROOT [INIT] Change to a different root file system\n"
6304 " suspend Suspend the system\n"
6305 " hibernate Hibernate the system\n"
6306 " hybrid-sleep Hibernate and suspend the system\n",
6307 program_invocation_short_name
);
6310 static void halt_help(void) {
6311 printf("%s [OPTIONS...]%s\n\n"
6312 "%s the system.\n\n"
6313 " --help Show this help\n"
6314 " --halt Halt the machine\n"
6315 " -p --poweroff Switch off the machine\n"
6316 " --reboot Reboot the machine\n"
6317 " -f --force Force immediate halt/power-off/reboot\n"
6318 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6319 " -d --no-wtmp Don't write wtmp record\n"
6320 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6321 program_invocation_short_name
,
6322 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6323 arg_action
== ACTION_REBOOT
? "Reboot" :
6324 arg_action
== ACTION_POWEROFF
? "Power off" :
6328 static void shutdown_help(void) {
6329 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6330 "Shut down the system.\n\n"
6331 " --help Show this help\n"
6332 " -H --halt Halt the machine\n"
6333 " -P --poweroff Power-off the machine\n"
6334 " -r --reboot Reboot the machine\n"
6335 " -h Equivalent to --poweroff, overridden by --halt\n"
6336 " -k Don't halt/power-off/reboot, just send warnings\n"
6337 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6338 " -c Cancel a pending shutdown\n",
6339 program_invocation_short_name
);
6342 static void telinit_help(void) {
6343 printf("%s [OPTIONS...] {COMMAND}\n\n"
6344 "Send control commands to the init daemon.\n\n"
6345 " --help Show this help\n"
6346 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6348 " 0 Power-off the machine\n"
6349 " 6 Reboot the machine\n"
6350 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6351 " 1, s, S Enter rescue mode\n"
6352 " q, Q Reload init daemon configuration\n"
6353 " u, U Reexecute init daemon\n",
6354 program_invocation_short_name
);
6357 static void runlevel_help(void) {
6358 printf("%s [OPTIONS...]\n\n"
6359 "Prints the previous and current runlevel of the init system.\n\n"
6360 " --help Show this help\n",
6361 program_invocation_short_name
);
6364 static void help_types(void) {
6368 puts("Available unit types:");
6369 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6370 puts(unit_type_to_string(i
));
6373 static void help_states(void) {
6377 puts("Available unit load states:");
6378 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6379 puts(unit_load_state_to_string(i
));
6382 puts("\nAvailable unit active states:");
6383 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6384 puts(unit_active_state_to_string(i
));
6387 puts("\nAvailable automount unit substates:");
6388 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6389 puts(automount_state_to_string(i
));
6392 puts("\nAvailable busname unit substates:");
6393 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6394 puts(busname_state_to_string(i
));
6397 puts("\nAvailable device unit substates:");
6398 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6399 puts(device_state_to_string(i
));
6402 puts("\nAvailable mount unit substates:");
6403 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6404 puts(mount_state_to_string(i
));
6407 puts("\nAvailable path unit substates:");
6408 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6409 puts(path_state_to_string(i
));
6412 puts("\nAvailable scope unit substates:");
6413 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6414 puts(scope_state_to_string(i
));
6417 puts("\nAvailable service unit substates:");
6418 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6419 puts(service_state_to_string(i
));
6422 puts("\nAvailable slice unit substates:");
6423 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6424 puts(slice_state_to_string(i
));
6427 puts("\nAvailable socket unit substates:");
6428 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6429 puts(socket_state_to_string(i
));
6432 puts("\nAvailable swap unit substates:");
6433 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6434 puts(swap_state_to_string(i
));
6437 puts("\nAvailable target unit substates:");
6438 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6439 puts(target_state_to_string(i
));
6442 puts("\nAvailable timer unit substates:");
6443 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6444 puts(timer_state_to_string(i
));
6447 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6456 ARG_IGNORE_DEPENDENCIES
,
6468 ARG_NO_ASK_PASSWORD
,
6481 static const struct option options
[] = {
6482 { "help", no_argument
, NULL
, 'h' },
6483 { "version", no_argument
, NULL
, ARG_VERSION
},
6484 { "type", required_argument
, NULL
, 't' },
6485 { "property", required_argument
, NULL
, 'p' },
6486 { "all", no_argument
, NULL
, 'a' },
6487 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6488 { "after", no_argument
, NULL
, ARG_AFTER
},
6489 { "before", no_argument
, NULL
, ARG_BEFORE
},
6490 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6491 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6492 { "full", no_argument
, NULL
, 'l' },
6493 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6494 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6495 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6496 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6497 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6498 { "user", no_argument
, NULL
, ARG_USER
},
6499 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6500 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6501 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6502 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6503 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6504 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6505 { "quiet", no_argument
, NULL
, 'q' },
6506 { "root", required_argument
, NULL
, ARG_ROOT
},
6507 { "force", no_argument
, NULL
, ARG_FORCE
},
6508 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6509 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6510 { "signal", required_argument
, NULL
, 's' },
6511 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6512 { "host", required_argument
, NULL
, 'H' },
6513 { "machine", required_argument
, NULL
, 'M' },
6514 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6515 { "lines", required_argument
, NULL
, 'n' },
6516 { "output", required_argument
, NULL
, 'o' },
6517 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6518 { "state", required_argument
, NULL
, ARG_STATE
},
6519 { "recursive", no_argument
, NULL
, 'r' },
6520 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6521 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6522 { "now", no_argument
, NULL
, ARG_NOW
},
6523 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6533 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6534 arg_ask_password
= true;
6536 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6548 if (isempty(optarg
)) {
6549 log_error("--type requires arguments.");
6555 _cleanup_free_
char *type
= NULL
;
6557 r
= extract_first_word(&p
, &type
, ",", 0);
6559 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6564 if (streq(type
, "help")) {
6569 if (unit_type_from_string(type
) >= 0) {
6570 if (strv_push(&arg_types
, type
) < 0)
6576 /* It's much nicer to use --state= for
6577 * load states, but let's support this
6578 * in --types= too for compatibility
6579 * with old versions */
6580 if (unit_load_state_from_string(type
) >= 0) {
6581 if (strv_push(&arg_states
, type
) < 0)
6587 log_error("Unknown unit type or load state '%s'.", type
);
6588 log_info("Use -t help to see a list of allowed values.");
6596 /* Make sure that if the empty property list
6597 was specified, we won't show any properties. */
6598 if (isempty(optarg
) && !arg_properties
) {
6599 arg_properties
= new0(char*, 1);
6600 if (!arg_properties
)
6605 _cleanup_free_
char *prop
= NULL
;
6607 r
= extract_first_word(&p
, &prop
, ",", 0);
6609 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6614 if (strv_push(&arg_properties
, prop
) < 0)
6621 /* If the user asked for a particular
6622 * property, show it to him, even if it is
6634 arg_dependency
= DEPENDENCY_REVERSE
;
6638 arg_dependency
= DEPENDENCY_AFTER
;
6642 arg_dependency
= DEPENDENCY_BEFORE
;
6645 case ARG_SHOW_TYPES
:
6646 arg_show_types
= true;
6650 arg_job_mode
= optarg
;
6654 arg_job_mode
= "fail";
6657 case ARG_IRREVERSIBLE
:
6658 arg_job_mode
= "replace-irreversibly";
6661 case ARG_IGNORE_DEPENDENCIES
:
6662 arg_job_mode
= "ignore-dependencies";
6666 arg_scope
= UNIT_FILE_USER
;
6670 arg_scope
= UNIT_FILE_SYSTEM
;
6674 arg_scope
= UNIT_FILE_GLOBAL
;
6678 arg_no_block
= true;
6682 arg_no_legend
= true;
6686 arg_no_pager
= true;
6694 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6704 if (strv_extend(&arg_states
, "failed") < 0)
6722 arg_no_reload
= true;
6726 arg_kill_who
= optarg
;
6730 arg_signal
= signal_from_string_try_harder(optarg
);
6731 if (arg_signal
< 0) {
6732 log_error("Failed to parse signal string %s.", optarg
);
6737 case ARG_NO_ASK_PASSWORD
:
6738 arg_ask_password
= false;
6742 arg_transport
= BUS_TRANSPORT_REMOTE
;
6747 arg_transport
= BUS_TRANSPORT_MACHINE
;
6756 if (safe_atou(optarg
, &arg_lines
) < 0) {
6757 log_error("Failed to parse lines '%s'", optarg
);
6763 arg_output
= output_mode_from_string(optarg
);
6764 if (arg_output
< 0) {
6765 log_error("Unknown output '%s'.", optarg
);
6771 arg_ignore_inhibitors
= true;
6778 case ARG_FIRMWARE_SETUP
:
6779 arg_firmware_setup
= true;
6783 if (isempty(optarg
)) {
6784 log_error("--signal requires arguments.");
6790 _cleanup_free_
char *s
= NULL
;
6792 r
= extract_first_word(&p
, &s
, ",", 0);
6794 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6799 if (streq(s
, "help")) {
6804 if (strv_push(&arg_states
, s
) < 0)
6813 if (geteuid() != 0) {
6814 log_error("--recursive requires root privileges.");
6818 arg_recursive
= true;
6821 case ARG_PRESET_MODE
:
6823 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6824 if (arg_preset_mode
< 0) {
6825 log_error("Failed to parse preset mode: %s.", optarg
);
6836 if (strv_extend(&arg_wall
, optarg
) < 0)
6844 assert_not_reached("Unhandled option");
6847 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6848 log_error("Cannot access user instance remotely.");
6855 static int halt_parse_argv(int argc
, char *argv
[]) {
6864 static const struct option options
[] = {
6865 { "help", no_argument
, NULL
, ARG_HELP
},
6866 { "halt", no_argument
, NULL
, ARG_HALT
},
6867 { "poweroff", no_argument
, NULL
, 'p' },
6868 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6869 { "force", no_argument
, NULL
, 'f' },
6870 { "wtmp-only", no_argument
, NULL
, 'w' },
6871 { "no-wtmp", no_argument
, NULL
, 'd' },
6872 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6881 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6882 if (runlevel
== '0' || runlevel
== '6')
6885 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6893 arg_action
= ACTION_HALT
;
6897 if (arg_action
!= ACTION_REBOOT
)
6898 arg_action
= ACTION_POWEROFF
;
6902 arg_action
= ACTION_REBOOT
;
6924 /* Compatibility nops */
6931 assert_not_reached("Unhandled option");
6934 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6935 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6938 } else if (optind
< argc
) {
6939 log_error("Too many arguments.");
6946 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
6950 if (streq(t
, "now"))
6952 else if (!strchr(t
, ':')) {
6955 if (safe_atou64(t
, &u
) < 0)
6958 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6967 hour
= strtol(t
, &e
, 10);
6968 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6971 minute
= strtol(e
+1, &e
, 10);
6972 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6975 n
= now(CLOCK_REALTIME
);
6976 s
= (time_t) (n
/ USEC_PER_SEC
);
6978 assert_se(localtime_r(&s
, &tm
));
6980 tm
.tm_hour
= (int) hour
;
6981 tm
.tm_min
= (int) minute
;
6984 assert_se(s
= mktime(&tm
));
6986 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6989 *_u
+= USEC_PER_DAY
;
6995 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7002 static const struct option options
[] = {
7003 { "help", no_argument
, NULL
, ARG_HELP
},
7004 { "halt", no_argument
, NULL
, 'H' },
7005 { "poweroff", no_argument
, NULL
, 'P' },
7006 { "reboot", no_argument
, NULL
, 'r' },
7007 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7008 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7018 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7026 arg_action
= ACTION_HALT
;
7030 arg_action
= ACTION_POWEROFF
;
7035 arg_action
= ACTION_KEXEC
;
7037 arg_action
= ACTION_REBOOT
;
7041 arg_action
= ACTION_KEXEC
;
7045 if (arg_action
!= ACTION_HALT
)
7046 arg_action
= ACTION_POWEROFF
;
7061 /* Compatibility nops */
7065 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7072 assert_not_reached("Unhandled option");
7075 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7076 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7078 log_error("Failed to parse time specification: %s", argv
[optind
]);
7082 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7084 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7085 /* No time argument for shutdown cancel */
7086 wall
= argv
+ optind
;
7087 else if (argc
> optind
+ 1)
7088 /* We skip the time argument */
7089 wall
= argv
+ optind
+ 1;
7092 arg_wall
= strv_copy(wall
);
7102 static int telinit_parse_argv(int argc
, char *argv
[]) {
7109 static const struct option options
[] = {
7110 { "help", no_argument
, NULL
, ARG_HELP
},
7111 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7115 static const struct {
7119 { '0', ACTION_POWEROFF
},
7120 { '6', ACTION_REBOOT
},
7121 { '1', ACTION_RESCUE
},
7122 { '2', ACTION_RUNLEVEL2
},
7123 { '3', ACTION_RUNLEVEL3
},
7124 { '4', ACTION_RUNLEVEL4
},
7125 { '5', ACTION_RUNLEVEL5
},
7126 { 's', ACTION_RESCUE
},
7127 { 'S', ACTION_RESCUE
},
7128 { 'q', ACTION_RELOAD
},
7129 { 'Q', ACTION_RELOAD
},
7130 { 'u', ACTION_REEXEC
},
7131 { 'U', ACTION_REEXEC
}
7140 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7155 assert_not_reached("Unhandled option");
7158 if (optind
>= argc
) {
7159 log_error("%s: required argument missing.", program_invocation_short_name
);
7163 if (optind
+ 1 < argc
) {
7164 log_error("Too many arguments.");
7168 if (strlen(argv
[optind
]) != 1) {
7169 log_error("Expected single character argument.");
7173 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7174 if (table
[i
].from
== argv
[optind
][0])
7177 if (i
>= ELEMENTSOF(table
)) {
7178 log_error("Unknown command '%s'.", argv
[optind
]);
7182 arg_action
= table
[i
].to
;
7189 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7195 static const struct option options
[] = {
7196 { "help", no_argument
, NULL
, ARG_HELP
},
7205 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7216 assert_not_reached("Unhandled option");
7219 if (optind
< argc
) {
7220 log_error("Too many arguments.");
7227 static int parse_argv(int argc
, char *argv
[]) {
7231 if (program_invocation_short_name
) {
7233 if (strstr(program_invocation_short_name
, "halt")) {
7234 arg_action
= ACTION_HALT
;
7235 return halt_parse_argv(argc
, argv
);
7236 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7237 arg_action
= ACTION_POWEROFF
;
7238 return halt_parse_argv(argc
, argv
);
7239 } else if (strstr(program_invocation_short_name
, "reboot")) {
7241 arg_action
= ACTION_KEXEC
;
7243 arg_action
= ACTION_REBOOT
;
7244 return halt_parse_argv(argc
, argv
);
7245 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7246 arg_action
= ACTION_POWEROFF
;
7247 return shutdown_parse_argv(argc
, argv
);
7248 } else if (strstr(program_invocation_short_name
, "init")) {
7250 if (sd_booted() > 0) {
7251 arg_action
= _ACTION_INVALID
;
7252 return telinit_parse_argv(argc
, argv
);
7254 /* Hmm, so some other init system is
7255 * running, we need to forward this
7256 * request to it. For now we simply
7257 * guess that it is Upstart. */
7259 execv(TELINIT
, argv
);
7261 log_error("Couldn't find an alternative telinit implementation to spawn.");
7265 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7266 arg_action
= ACTION_RUNLEVEL
;
7267 return runlevel_parse_argv(argc
, argv
);
7271 arg_action
= ACTION_SYSTEMCTL
;
7272 return systemctl_parse_argv(argc
, argv
);
7275 _pure_
static int action_to_runlevel(void) {
7277 static const char table
[_ACTION_MAX
] = {
7278 [ACTION_HALT
] = '0',
7279 [ACTION_POWEROFF
] = '0',
7280 [ACTION_REBOOT
] = '6',
7281 [ACTION_RUNLEVEL2
] = '2',
7282 [ACTION_RUNLEVEL3
] = '3',
7283 [ACTION_RUNLEVEL4
] = '4',
7284 [ACTION_RUNLEVEL5
] = '5',
7285 [ACTION_RESCUE
] = '1'
7288 assert(arg_action
< _ACTION_MAX
);
7290 return table
[arg_action
];
7293 static int talk_initctl(void) {
7294 #ifdef HAVE_SYSV_COMPAT
7295 struct init_request request
= {
7296 .magic
= INIT_MAGIC
,
7298 .cmd
= INIT_CMD_RUNLVL
7301 _cleanup_close_
int fd
= -1;
7305 rl
= action_to_runlevel();
7309 request
.runlevel
= rl
;
7311 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7313 if (errno
== ENOENT
)
7316 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7319 r
= loop_write(fd
, &request
, sizeof(request
), false);
7321 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7329 static int systemctl_main(int argc
, char *argv
[]) {
7331 static const Verb verbs
[] = {
7332 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7333 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7334 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7335 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7336 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7337 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7338 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7339 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7340 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7341 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7342 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7343 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7344 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7345 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7346 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7347 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7348 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7349 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7350 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7351 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7352 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7353 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7354 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7355 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7356 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7357 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7358 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7359 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7360 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7361 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7362 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7363 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7364 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7365 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7366 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7367 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7368 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7369 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7370 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7371 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7372 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7373 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7374 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7375 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7376 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7377 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7378 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7379 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7380 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7381 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7382 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7383 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7384 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7385 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7386 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7387 { "link", 2, VERB_ANY
, 0, enable_unit
},
7388 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7389 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7390 { "set-default", 2, 2, 0, set_default
},
7391 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7392 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7393 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7394 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7395 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7396 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7400 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7403 static int reload_with_fallback(void) {
7405 /* First, try systemd via D-Bus. */
7406 if (daemon_reload(0, NULL
, NULL
) >= 0)
7409 /* Nothing else worked, so let's try signals */
7410 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7412 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7413 return log_error_errno(errno
, "kill() failed: %m");
7418 static int start_with_fallback(void) {
7420 /* First, try systemd via D-Bus. */
7421 if (start_unit(0, NULL
, NULL
) >= 0)
7424 /* Nothing else worked, so let's try
7426 if (talk_initctl() > 0)
7429 log_error("Failed to talk to init daemon.");
7433 static int halt_now(enum action a
) {
7435 /* The kernel will automaticall flush ATA disks and suchlike
7436 * on reboot(), but the file systems need to be synce'd
7437 * explicitly in advance. */
7440 /* Make sure C-A-D is handled by the kernel from this point
7442 (void) reboot(RB_ENABLE_CAD
);
7447 log_info("Halting.");
7448 (void) reboot(RB_HALT_SYSTEM
);
7451 case ACTION_POWEROFF
:
7452 log_info("Powering off.");
7453 (void) reboot(RB_POWER_OFF
);
7457 case ACTION_REBOOT
: {
7458 _cleanup_free_
char *param
= NULL
;
7460 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7461 log_info("Rebooting with argument '%s'.", param
);
7462 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7465 log_info("Rebooting.");
7466 (void) reboot(RB_AUTOBOOT
);
7471 assert_not_reached("Unknown action.");
7475 static int logind_schedule_shutdown(void) {
7478 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7479 char date
[FORMAT_TIMESTAMP_MAX
];
7484 (void) logind_set_wall_message();
7486 r
= acquire_bus(BUS_FULL
, &bus
);
7490 switch (arg_action
) {
7494 case ACTION_POWEROFF
:
7495 action
= "poweroff";
7510 action
= strjoina("dry-", action
);
7512 r
= sd_bus_call_method(
7514 "org.freedesktop.login1",
7515 "/org/freedesktop/login1",
7516 "org.freedesktop.login1.Manager",
7524 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7526 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7529 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7534 static int halt_main(void) {
7537 r
= logind_check_inhibitors(arg_action
);
7542 return logind_schedule_shutdown();
7544 if (geteuid() != 0) {
7545 if (arg_dry
|| arg_force
> 0) {
7546 log_error("Must be root.");
7550 /* Try logind if we are a normal user and no special
7551 * mode applies. Maybe PolicyKit allows us to shutdown
7553 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7554 r
= logind_reboot(arg_action
);
7557 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7558 /* requested operation is not
7559 * supported on the local system or
7560 * already in progress */
7562 /* on all other errors, try low-level operation */
7566 if (!arg_dry
&& !arg_force
)
7567 return start_with_fallback();
7569 assert(geteuid() == 0);
7572 if (sd_booted() > 0)
7573 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7575 r
= utmp_put_shutdown();
7577 log_warning_errno(r
, "Failed to write utmp record: %m");
7584 r
= halt_now(arg_action
);
7585 return log_error_errno(r
, "Failed to reboot: %m");
7588 static int runlevel_main(void) {
7589 int r
, runlevel
, previous
;
7591 r
= utmp_get_runlevel(&runlevel
, &previous
);
7598 previous
<= 0 ? 'N' : previous
,
7599 runlevel
<= 0 ? 'N' : runlevel
);
7604 static int logind_cancel_shutdown(void) {
7606 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7610 r
= acquire_bus(BUS_FULL
, &bus
);
7614 (void) logind_set_wall_message();
7616 r
= sd_bus_call_method(
7618 "org.freedesktop.login1",
7619 "/org/freedesktop/login1",
7620 "org.freedesktop.login1.Manager",
7621 "CancelScheduledShutdown",
7625 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7629 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7634 int main(int argc
, char*argv
[]) {
7637 setlocale(LC_ALL
, "");
7638 log_parse_environment();
7641 /* Explicitly not on_tty() to avoid setting cached value.
7642 * This becomes relevant for piping output which might be
7644 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7646 r
= parse_argv(argc
, argv
);
7650 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7651 log_info("Running in chroot, ignoring request.");
7656 /* systemctl_main() will print an error message for the bus
7657 * connection, but only if it needs to */
7659 switch (arg_action
) {
7661 case ACTION_SYSTEMCTL
:
7662 r
= systemctl_main(argc
, argv
);
7666 case ACTION_POWEROFF
:
7672 case ACTION_RUNLEVEL2
:
7673 case ACTION_RUNLEVEL3
:
7674 case ACTION_RUNLEVEL4
:
7675 case ACTION_RUNLEVEL5
:
7677 case ACTION_EMERGENCY
:
7678 case ACTION_DEFAULT
:
7679 r
= start_with_fallback();
7684 r
= reload_with_fallback();
7687 case ACTION_CANCEL_SHUTDOWN
:
7688 r
= logind_cancel_shutdown();
7691 case ACTION_RUNLEVEL
:
7692 r
= runlevel_main();
7695 case _ACTION_INVALID
:
7697 assert_not_reached("Unknown action");
7702 ask_password_agent_close();
7703 polkit_agent_close();
7705 strv_free(arg_types
);
7706 strv_free(arg_states
);
7707 strv_free(arg_properties
);
7709 strv_free(arg_wall
);
7714 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7716 return r
< 0 ? EXIT_FAILURE
: r
;