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
= 0;
2782 const char* extra_args
[4] = {};
2784 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2785 extra_args
[arg_count
++] = "--user";
2787 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2788 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2789 extra_args
[arg_count
++] = "-H";
2790 extra_args
[arg_count
++] = arg_host
;
2791 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2792 extra_args
[arg_count
++] = "-M";
2793 extra_args
[arg_count
++] = arg_host
;
2796 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2800 /* When stopping units, warn if they can still be triggered by
2801 * another active unit (socket, path, timer) */
2802 if (!arg_quiet
&& streq(method
, "StopUnit"))
2803 STRV_FOREACH(name
, names
)
2804 check_triggering_units(bus
, *name
);
2810 static int logind_set_wall_message(void) {
2812 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2814 _cleanup_free_
char *m
= NULL
;
2817 r
= acquire_bus(BUS_FULL
, &bus
);
2821 m
= strv_join(arg_wall
, " ");
2825 r
= sd_bus_call_method(
2827 "org.freedesktop.login1",
2828 "/org/freedesktop/login1",
2829 "org.freedesktop.login1.Manager",
2838 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2844 /* Ask systemd-logind, which might grant access to unprivileged users
2845 * through PolicyKit */
2846 static int logind_reboot(enum action a
) {
2848 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2849 const char *method
, *description
;
2853 polkit_agent_open_if_enabled();
2854 (void) logind_set_wall_message();
2856 r
= acquire_bus(BUS_FULL
, &bus
);
2864 description
= "reboot system";
2867 case ACTION_POWEROFF
:
2868 method
= "PowerOff";
2869 description
= "power off system";
2872 case ACTION_SUSPEND
:
2874 description
= "suspend system";
2877 case ACTION_HIBERNATE
:
2878 method
= "Hibernate";
2879 description
= "hibernate system";
2882 case ACTION_HYBRID_SLEEP
:
2883 method
= "HybridSleep";
2884 description
= "put system into hybrid sleep";
2891 r
= sd_bus_call_method(
2893 "org.freedesktop.login1",
2894 "/org/freedesktop/login1",
2895 "org.freedesktop.login1.Manager",
2899 "b", arg_ask_password
);
2901 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2909 static int logind_check_inhibitors(enum action a
) {
2911 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2912 _cleanup_strv_free_
char **sessions
= NULL
;
2913 const char *what
, *who
, *why
, *mode
;
2920 if (arg_ignore_inhibitors
|| arg_force
> 0)
2932 r
= acquire_bus(BUS_FULL
, &bus
);
2936 r
= sd_bus_call_method(
2938 "org.freedesktop.login1",
2939 "/org/freedesktop/login1",
2940 "org.freedesktop.login1.Manager",
2946 /* If logind is not around, then there are no inhibitors... */
2949 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2951 return bus_log_parse_error(r
);
2953 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2954 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2955 _cleanup_strv_free_
char **sv
= NULL
;
2957 if (!streq(mode
, "block"))
2960 sv
= strv_split(what
, ":");
2964 if ((pid_t
) pid
< 0)
2965 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2967 if (!strv_contains(sv
,
2972 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2975 get_process_comm(pid
, &comm
);
2976 user
= uid_to_name(uid
);
2978 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2979 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2984 return bus_log_parse_error(r
);
2986 r
= sd_bus_message_exit_container(reply
);
2988 return bus_log_parse_error(r
);
2990 /* Check for current sessions */
2991 sd_get_sessions(&sessions
);
2992 STRV_FOREACH(s
, sessions
) {
2993 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2995 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2998 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3001 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3004 sd_session_get_tty(*s
, &tty
);
3005 sd_session_get_seat(*s
, &seat
);
3006 sd_session_get_service(*s
, &service
);
3007 user
= uid_to_name(uid
);
3009 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3016 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3017 action_table
[a
].verb
);
3025 static int logind_prepare_firmware_setup(void) {
3027 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3031 r
= acquire_bus(BUS_FULL
, &bus
);
3035 r
= sd_bus_call_method(
3037 "org.freedesktop.login1",
3038 "/org/freedesktop/login1",
3039 "org.freedesktop.login1.Manager",
3040 "SetRebootToFirmwareSetup",
3045 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3049 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3054 static int prepare_firmware_setup(void) {
3057 if (!arg_firmware_setup
)
3060 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3062 r
= efi_set_reboot_to_firmware(true);
3064 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3069 return logind_prepare_firmware_setup();
3072 static int set_exit_code(uint8_t code
) {
3073 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3077 r
= acquire_bus(BUS_MANAGER
, &bus
);
3081 r
= sd_bus_call_method(
3083 "org.freedesktop.systemd1",
3084 "/org/freedesktop/systemd1",
3085 "org.freedesktop.systemd1.Manager",
3091 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3096 static int start_special(int argc
, char *argv
[], void *userdata
) {
3102 a
= verb_to_action(argv
[0]);
3104 r
= logind_check_inhibitors(a
);
3108 if (arg_force
>= 2 && geteuid() != 0) {
3109 log_error("Must be root.");
3113 r
= prepare_firmware_setup();
3117 if (a
== ACTION_REBOOT
&& argc
> 1) {
3118 r
= update_reboot_param_file(argv
[1]);
3122 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3125 /* If the exit code is not given on the command line,
3126 * don't reset it to zero: just keep it as it might
3127 * have been set previously. */
3129 r
= safe_atou8(argv
[1], &code
);
3131 return log_error_errno(r
, "Invalid exit code.");
3133 r
= set_exit_code(code
);
3138 if (arg_force
>= 2 &&
3145 if (arg_force
>= 1 &&
3152 return daemon_reload(argc
, argv
, userdata
);
3154 /* First try logind, to allow authentication with polkit */
3160 ACTION_HYBRID_SLEEP
)) {
3161 r
= logind_reboot(a
);
3164 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3165 /* requested operation is not supported or already in progress */
3168 /* On all other errors, try low-level operation */
3171 return start_unit(argc
, argv
, userdata
);
3174 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3175 _cleanup_strv_free_
char **names
= NULL
;
3181 r
= acquire_bus(BUS_MANAGER
, &bus
);
3185 r
= expand_names(bus
, args
, NULL
, &names
);
3187 return log_error_errno(r
, "Failed to expand names: %m");
3189 STRV_FOREACH(name
, names
) {
3192 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3199 /* use the given return code for the case that we won't find
3200 * any unit which matches the list */
3201 return found
? 0 : code
;
3204 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3205 /* According to LSB: 3, "program is not running" */
3206 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3209 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3210 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3213 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3214 _cleanup_strv_free_
char **names
= NULL
;
3215 char *kill_who
= NULL
, **name
;
3219 polkit_agent_open_if_enabled();
3221 r
= acquire_bus(BUS_MANAGER
, &bus
);
3226 arg_kill_who
= "all";
3228 /* --fail was specified */
3229 if (streq(arg_job_mode
, "fail"))
3230 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3232 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3234 return log_error_errno(r
, "Failed to expand names: %m");
3236 STRV_FOREACH(name
, names
) {
3237 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3239 q
= sd_bus_call_method(
3241 "org.freedesktop.systemd1",
3242 "/org/freedesktop/systemd1",
3243 "org.freedesktop.systemd1.Manager",
3247 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3249 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3258 typedef struct ExecStatusInfo
{
3266 usec_t start_timestamp
;
3267 usec_t exit_timestamp
;
3272 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3275 static void exec_status_info_free(ExecStatusInfo
*i
) {
3284 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3285 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3288 int32_t code
, status
;
3294 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3296 return bus_log_parse_error(r
);
3300 r
= sd_bus_message_read(m
, "s", &path
);
3302 return bus_log_parse_error(r
);
3304 i
->path
= strdup(path
);
3308 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3310 return bus_log_parse_error(r
);
3312 r
= sd_bus_message_read(m
,
3315 &start_timestamp
, &start_timestamp_monotonic
,
3316 &exit_timestamp
, &exit_timestamp_monotonic
,
3320 return bus_log_parse_error(r
);
3323 i
->start_timestamp
= (usec_t
) start_timestamp
;
3324 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3325 i
->pid
= (pid_t
) pid
;
3329 r
= sd_bus_message_exit_container(m
);
3331 return bus_log_parse_error(r
);
3336 typedef struct UnitStatusInfo
{
3338 const char *load_state
;
3339 const char *active_state
;
3340 const char *sub_state
;
3341 const char *unit_file_state
;
3342 const char *unit_file_preset
;
3344 const char *description
;
3345 const char *following
;
3347 char **documentation
;
3349 const char *fragment_path
;
3350 const char *source_path
;
3351 const char *control_group
;
3353 char **dropin_paths
;
3355 const char *load_error
;
3358 usec_t inactive_exit_timestamp
;
3359 usec_t inactive_exit_timestamp_monotonic
;
3360 usec_t active_enter_timestamp
;
3361 usec_t active_exit_timestamp
;
3362 usec_t inactive_enter_timestamp
;
3364 bool need_daemon_reload
;
3370 const char *status_text
;
3371 const char *pid_file
;
3375 usec_t start_timestamp
;
3376 usec_t exit_timestamp
;
3378 int exit_code
, exit_status
;
3380 usec_t condition_timestamp
;
3381 bool condition_result
;
3382 bool failed_condition_trigger
;
3383 bool failed_condition_negate
;
3384 const char *failed_condition
;
3385 const char *failed_condition_parameter
;
3387 usec_t assert_timestamp
;
3389 bool failed_assert_trigger
;
3390 bool failed_assert_negate
;
3391 const char *failed_assert
;
3392 const char *failed_assert_parameter
;
3395 unsigned n_accepted
;
3396 unsigned n_connections
;
3399 /* Pairs of type, path */
3403 const char *sysfs_path
;
3405 /* Mount, Automount */
3412 uint64_t memory_current
;
3413 uint64_t memory_limit
;
3414 uint64_t cpu_usage_nsec
;
3415 uint64_t tasks_current
;
3418 LIST_HEAD(ExecStatusInfo
, exec
);
3421 static void print_status_info(
3426 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3428 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3429 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3435 /* This shows pretty information about a unit. See
3436 * print_property() for a low-level property printer */
3438 if (streq_ptr(i
->active_state
, "failed")) {
3439 active_on
= ansi_highlight_red();
3440 active_off
= ansi_normal();
3441 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3442 active_on
= ansi_highlight_green();
3443 active_off
= ansi_normal();
3445 active_on
= active_off
= "";
3447 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3449 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3450 printf(" - %s", i
->description
);
3455 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3457 if (streq_ptr(i
->load_state
, "error")) {
3458 on
= ansi_highlight_red();
3459 off
= ansi_normal();
3463 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3465 if (i
->load_error
!= 0)
3466 printf(" Loaded: %s%s%s (Reason: %s)\n",
3467 on
, strna(i
->load_state
), off
, i
->load_error
);
3468 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3469 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3470 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3471 else if (path
&& !isempty(i
->unit_file_state
))
3472 printf(" Loaded: %s%s%s (%s; %s)\n",
3473 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3475 printf(" Loaded: %s%s%s (%s)\n",
3476 on
, strna(i
->load_state
), off
, path
);
3478 printf(" Loaded: %s%s%s\n",
3479 on
, strna(i
->load_state
), off
);
3482 printf("Transient: yes\n");
3484 if (!strv_isempty(i
->dropin_paths
)) {
3485 _cleanup_free_
char *dir
= NULL
;
3489 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3490 if (! dir
|| last
) {
3491 printf(dir
? " " : " Drop-In: ");
3495 dir
= dirname_malloc(*dropin
);
3501 printf("%s\n %s", dir
,
3502 draw_special_char(DRAW_TREE_RIGHT
));
3505 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3507 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3511 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3513 printf(" Active: %s%s (%s)%s",
3514 active_on
, strna(i
->active_state
), ss
, active_off
);
3516 printf(" Active: %s%s%s",
3517 active_on
, strna(i
->active_state
), active_off
);
3519 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3520 printf(" (Result: %s)", i
->result
);
3522 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3523 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3524 (streq_ptr(i
->active_state
, "inactive") ||
3525 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3526 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3527 i
->active_exit_timestamp
;
3529 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3530 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3533 printf(" since %s; %s\n", s2
, s1
);
3535 printf(" since %s\n", s2
);
3539 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3540 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3541 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3543 printf("Condition: start %scondition failed%s at %s%s%s\n",
3544 ansi_highlight_yellow(), ansi_normal(),
3545 s2
, s1
? "; " : "", strempty(s1
));
3546 if (i
->failed_condition_trigger
)
3547 printf(" none of the trigger conditions were met\n");
3548 else if (i
->failed_condition
)
3549 printf(" %s=%s%s was not met\n",
3550 i
->failed_condition
,
3551 i
->failed_condition_negate
? "!" : "",
3552 i
->failed_condition_parameter
);
3555 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3556 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3557 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3559 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3560 ansi_highlight_red(), ansi_normal(),
3561 s2
, s1
? "; " : "", strempty(s1
));
3562 if (i
->failed_assert_trigger
)
3563 printf(" none of the trigger assertions were met\n");
3564 else if (i
->failed_assert
)
3565 printf(" %s=%s%s was not met\n",
3567 i
->failed_assert_negate
? "!" : "",
3568 i
->failed_assert_parameter
);
3572 printf(" Device: %s\n", i
->sysfs_path
);
3574 printf(" Where: %s\n", i
->where
);
3576 printf(" What: %s\n", i
->what
);
3578 STRV_FOREACH(t
, i
->documentation
)
3579 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3581 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3582 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3585 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3587 LIST_FOREACH(exec
, p
, i
->exec
) {
3588 _cleanup_free_
char *argv
= NULL
;
3591 /* Only show exited processes here */
3595 argv
= strv_join(p
->argv
, " ");
3596 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3598 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3600 on
= ansi_highlight_red();
3601 off
= ansi_normal();
3605 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3607 if (p
->code
== CLD_EXITED
) {
3610 printf("status=%i", p
->status
);
3612 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3617 printf("signal=%s", signal_to_string(p
->status
));
3619 printf(")%s\n", off
);
3621 if (i
->main_pid
== p
->pid
&&
3622 i
->start_timestamp
== p
->start_timestamp
&&
3623 i
->exit_timestamp
== p
->start_timestamp
)
3624 /* Let's not show this twice */
3627 if (p
->pid
== i
->control_pid
)
3631 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3632 if (i
->main_pid
> 0) {
3633 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3636 _cleanup_free_
char *comm
= NULL
;
3637 get_process_comm(i
->main_pid
, &comm
);
3639 printf(" (%s)", comm
);
3640 } else if (i
->exit_code
> 0) {
3641 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3643 if (i
->exit_code
== CLD_EXITED
) {
3646 printf("status=%i", i
->exit_status
);
3648 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3653 printf("signal=%s", signal_to_string(i
->exit_status
));
3657 if (i
->control_pid
> 0)
3661 if (i
->control_pid
> 0) {
3662 _cleanup_free_
char *c
= NULL
;
3664 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3666 get_process_comm(i
->control_pid
, &c
);
3675 printf(" Status: \"%s\"\n", i
->status_text
);
3676 if (i
->status_errno
> 0)
3677 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3679 if (i
->tasks_current
!= (uint64_t) -1) {
3680 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3682 if (i
->tasks_max
!= (uint64_t) -1)
3683 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3688 if (i
->memory_current
!= (uint64_t) -1) {
3689 char buf
[FORMAT_BYTES_MAX
];
3691 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3693 if (i
->memory_limit
!= (uint64_t) -1)
3694 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3699 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3700 char buf
[FORMAT_TIMESPAN_MAX
];
3701 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3704 if (i
->control_group
&&
3705 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3706 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3709 printf(" CGroup: %s\n", i
->control_group
);
3711 if (IN_SET(arg_transport
,
3712 BUS_TRANSPORT_LOCAL
,
3713 BUS_TRANSPORT_MACHINE
)) {
3716 static const char prefix
[] = " ";
3719 if (c
> sizeof(prefix
) - 1)
3720 c
-= sizeof(prefix
) - 1;
3724 if (i
->main_pid
> 0)
3725 extra
[k
++] = i
->main_pid
;
3727 if (i
->control_pid
> 0)
3728 extra
[k
++] = i
->control_pid
;
3730 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3734 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3735 show_journal_by_unit(
3740 i
->inactive_exit_timestamp_monotonic
,
3743 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3744 SD_JOURNAL_LOCAL_ONLY
,
3745 arg_scope
== UNIT_FILE_SYSTEM
,
3748 if (i
->need_daemon_reload
)
3749 warn_unit_file_changed(i
->id
);
3752 static void show_unit_help(UnitStatusInfo
*i
) {
3757 if (!i
->documentation
) {
3758 log_info("Documentation for %s not known.", i
->id
);
3762 STRV_FOREACH(p
, i
->documentation
)
3763 if (startswith(*p
, "man:"))
3764 show_man_page(*p
+ 4, false);
3766 log_info("Can't show: %s", *p
);
3769 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3776 switch (contents
[0]) {
3778 case SD_BUS_TYPE_STRING
: {
3781 r
= sd_bus_message_read(m
, "s", &s
);
3783 return bus_log_parse_error(r
);
3786 if (streq(name
, "Id"))
3788 else if (streq(name
, "LoadState"))
3790 else if (streq(name
, "ActiveState"))
3791 i
->active_state
= s
;
3792 else if (streq(name
, "SubState"))
3794 else if (streq(name
, "Description"))
3796 else if (streq(name
, "FragmentPath"))
3797 i
->fragment_path
= s
;
3798 else if (streq(name
, "SourcePath"))
3801 else if (streq(name
, "DefaultControlGroup")) {
3803 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3805 i
->control_group
= e
;
3808 else if (streq(name
, "ControlGroup"))
3809 i
->control_group
= s
;
3810 else if (streq(name
, "StatusText"))
3812 else if (streq(name
, "PIDFile"))
3814 else if (streq(name
, "SysFSPath"))
3816 else if (streq(name
, "Where"))
3818 else if (streq(name
, "What"))
3820 else if (streq(name
, "Following"))
3822 else if (streq(name
, "UnitFileState"))
3823 i
->unit_file_state
= s
;
3824 else if (streq(name
, "UnitFilePreset"))
3825 i
->unit_file_preset
= s
;
3826 else if (streq(name
, "Result"))
3833 case SD_BUS_TYPE_BOOLEAN
: {
3836 r
= sd_bus_message_read(m
, "b", &b
);
3838 return bus_log_parse_error(r
);
3840 if (streq(name
, "Accept"))
3842 else if (streq(name
, "NeedDaemonReload"))
3843 i
->need_daemon_reload
= b
;
3844 else if (streq(name
, "ConditionResult"))
3845 i
->condition_result
= b
;
3846 else if (streq(name
, "AssertResult"))
3847 i
->assert_result
= b
;
3848 else if (streq(name
, "Transient"))
3854 case SD_BUS_TYPE_UINT32
: {
3857 r
= sd_bus_message_read(m
, "u", &u
);
3859 return bus_log_parse_error(r
);
3861 if (streq(name
, "MainPID")) {
3863 i
->main_pid
= (pid_t
) u
;
3866 } else if (streq(name
, "ControlPID"))
3867 i
->control_pid
= (pid_t
) u
;
3868 else if (streq(name
, "ExecMainPID")) {
3870 i
->main_pid
= (pid_t
) u
;
3871 } else if (streq(name
, "NAccepted"))
3873 else if (streq(name
, "NConnections"))
3874 i
->n_connections
= u
;
3879 case SD_BUS_TYPE_INT32
: {
3882 r
= sd_bus_message_read(m
, "i", &j
);
3884 return bus_log_parse_error(r
);
3886 if (streq(name
, "ExecMainCode"))
3887 i
->exit_code
= (int) j
;
3888 else if (streq(name
, "ExecMainStatus"))
3889 i
->exit_status
= (int) j
;
3890 else if (streq(name
, "StatusErrno"))
3891 i
->status_errno
= (int) j
;
3896 case SD_BUS_TYPE_UINT64
: {
3899 r
= sd_bus_message_read(m
, "t", &u
);
3901 return bus_log_parse_error(r
);
3903 if (streq(name
, "ExecMainStartTimestamp"))
3904 i
->start_timestamp
= (usec_t
) u
;
3905 else if (streq(name
, "ExecMainExitTimestamp"))
3906 i
->exit_timestamp
= (usec_t
) u
;
3907 else if (streq(name
, "ActiveEnterTimestamp"))
3908 i
->active_enter_timestamp
= (usec_t
) u
;
3909 else if (streq(name
, "InactiveEnterTimestamp"))
3910 i
->inactive_enter_timestamp
= (usec_t
) u
;
3911 else if (streq(name
, "InactiveExitTimestamp"))
3912 i
->inactive_exit_timestamp
= (usec_t
) u
;
3913 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3914 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3915 else if (streq(name
, "ActiveExitTimestamp"))
3916 i
->active_exit_timestamp
= (usec_t
) u
;
3917 else if (streq(name
, "ConditionTimestamp"))
3918 i
->condition_timestamp
= (usec_t
) u
;
3919 else if (streq(name
, "AssertTimestamp"))
3920 i
->assert_timestamp
= (usec_t
) u
;
3921 else if (streq(name
, "MemoryCurrent"))
3922 i
->memory_current
= u
;
3923 else if (streq(name
, "MemoryLimit"))
3924 i
->memory_limit
= u
;
3925 else if (streq(name
, "TasksCurrent"))
3926 i
->tasks_current
= u
;
3927 else if (streq(name
, "TasksMax"))
3929 else if (streq(name
, "CPUUsageNSec"))
3930 i
->cpu_usage_nsec
= u
;
3935 case SD_BUS_TYPE_ARRAY
:
3937 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3938 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3940 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3942 return bus_log_parse_error(r
);
3944 info
= new0(ExecStatusInfo
, 1);
3948 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3950 info
->name
= strdup(name
);
3954 LIST_PREPEND(exec
, i
->exec
, info
);
3956 info
= new0(ExecStatusInfo
, 1);
3962 return bus_log_parse_error(r
);
3964 r
= sd_bus_message_exit_container(m
);
3966 return bus_log_parse_error(r
);
3970 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3971 const char *type
, *path
;
3973 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3975 return bus_log_parse_error(r
);
3977 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3979 r
= strv_extend(&i
->listen
, type
);
3983 r
= strv_extend(&i
->listen
, path
);
3988 return bus_log_parse_error(r
);
3990 r
= sd_bus_message_exit_container(m
);
3992 return bus_log_parse_error(r
);
3996 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3998 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4000 return bus_log_parse_error(r
);
4002 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4004 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4006 return bus_log_parse_error(r
);
4008 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4009 const char *cond
, *param
;
4010 int trigger
, negate
;
4013 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4015 return bus_log_parse_error(r
);
4017 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4018 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4019 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4020 i
->failed_condition
= cond
;
4021 i
->failed_condition_trigger
= trigger
;
4022 i
->failed_condition_negate
= negate
;
4023 i
->failed_condition_parameter
= param
;
4027 return bus_log_parse_error(r
);
4029 r
= sd_bus_message_exit_container(m
);
4031 return bus_log_parse_error(r
);
4033 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4034 const char *cond
, *param
;
4035 int trigger
, negate
;
4038 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4040 return bus_log_parse_error(r
);
4042 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4043 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4044 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4045 i
->failed_assert
= cond
;
4046 i
->failed_assert_trigger
= trigger
;
4047 i
->failed_assert_negate
= negate
;
4048 i
->failed_assert_parameter
= param
;
4052 return bus_log_parse_error(r
);
4054 r
= sd_bus_message_exit_container(m
);
4056 return bus_log_parse_error(r
);
4063 case SD_BUS_TYPE_STRUCT_BEGIN
:
4065 if (streq(name
, "LoadError")) {
4066 const char *n
, *message
;
4068 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4070 return bus_log_parse_error(r
);
4072 if (!isempty(message
))
4073 i
->load_error
= message
;
4086 r
= sd_bus_message_skip(m
, contents
);
4088 return bus_log_parse_error(r
);
4093 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4099 /* This is a low-level property printer, see
4100 * print_status_info() for the nicer output */
4102 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4103 /* skip what we didn't read */
4104 r
= sd_bus_message_skip(m
, contents
);
4108 switch (contents
[0]) {
4110 case SD_BUS_TYPE_STRUCT_BEGIN
:
4112 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4115 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4117 return bus_log_parse_error(r
);
4120 printf("%s=%"PRIu32
"\n", name
, u
);
4122 printf("%s=\n", name
);
4126 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4129 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4131 return bus_log_parse_error(r
);
4133 if (arg_all
|| !isempty(s
))
4134 printf("%s=%s\n", name
, s
);
4138 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4139 const char *a
= NULL
, *b
= NULL
;
4141 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4143 return bus_log_parse_error(r
);
4145 if (arg_all
|| !isempty(a
) || !isempty(b
))
4146 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4149 } else if (streq_ptr(name
, "SystemCallFilter")) {
4150 _cleanup_strv_free_
char **l
= NULL
;
4153 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4155 return bus_log_parse_error(r
);
4157 r
= sd_bus_message_read(m
, "b", &whitelist
);
4159 return bus_log_parse_error(r
);
4161 r
= sd_bus_message_read_strv(m
, &l
);
4163 return bus_log_parse_error(r
);
4165 r
= sd_bus_message_exit_container(m
);
4167 return bus_log_parse_error(r
);
4169 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4173 fputs(name
, stdout
);
4179 STRV_FOREACH(i
, l
) {
4187 fputc('\n', stdout
);
4195 case SD_BUS_TYPE_ARRAY
:
4197 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4201 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4203 return bus_log_parse_error(r
);
4205 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4206 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4209 return bus_log_parse_error(r
);
4211 r
= sd_bus_message_exit_container(m
);
4213 return bus_log_parse_error(r
);
4217 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4218 const char *type
, *path
;
4220 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4222 return bus_log_parse_error(r
);
4224 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4225 printf("%s=%s\n", type
, path
);
4227 return bus_log_parse_error(r
);
4229 r
= sd_bus_message_exit_container(m
);
4231 return bus_log_parse_error(r
);
4235 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4236 const char *type
, *path
;
4238 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4240 return bus_log_parse_error(r
);
4242 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4243 printf("Listen%s=%s\n", type
, path
);
4245 return bus_log_parse_error(r
);
4247 r
= sd_bus_message_exit_container(m
);
4249 return bus_log_parse_error(r
);
4253 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4255 uint64_t value
, next_elapse
;
4257 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4259 return bus_log_parse_error(r
);
4261 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4262 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4264 printf("%s={ value=%s ; next_elapse=%s }\n",
4266 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4267 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4270 return bus_log_parse_error(r
);
4272 r
= sd_bus_message_exit_container(m
);
4274 return bus_log_parse_error(r
);
4278 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4279 ExecStatusInfo info
= {};
4281 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4283 return bus_log_parse_error(r
);
4285 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4286 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4287 _cleanup_free_
char *tt
;
4289 tt
= strv_join(info
.argv
, " ");
4291 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",
4295 yes_no(info
.ignore
),
4296 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4297 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4299 sigchld_code_to_string(info
.code
),
4301 info
.code
== CLD_EXITED
? "" : "/",
4302 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4305 strv_free(info
.argv
);
4309 r
= sd_bus_message_exit_container(m
);
4311 return bus_log_parse_error(r
);
4315 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4316 const char *path
, *rwm
;
4318 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4320 return bus_log_parse_error(r
);
4322 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4323 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4325 return bus_log_parse_error(r
);
4327 r
= sd_bus_message_exit_container(m
);
4329 return bus_log_parse_error(r
);
4333 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4337 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4339 return bus_log_parse_error(r
);
4341 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4342 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4344 return bus_log_parse_error(r
);
4346 r
= sd_bus_message_exit_container(m
);
4348 return bus_log_parse_error(r
);
4352 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4356 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4358 return bus_log_parse_error(r
);
4360 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4361 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4363 return bus_log_parse_error(r
);
4365 r
= sd_bus_message_exit_container(m
);
4367 return bus_log_parse_error(r
);
4375 r
= bus_print_property(name
, m
, arg_all
);
4377 return bus_log_parse_error(r
);
4380 r
= sd_bus_message_skip(m
, contents
);
4382 return bus_log_parse_error(r
);
4385 printf("%s=[unprintable]\n", name
);
4391 static int show_one(
4395 bool show_properties
,
4399 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4400 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4401 UnitStatusInfo info
= {
4402 .memory_current
= (uint64_t) -1,
4403 .memory_limit
= (uint64_t) -1,
4404 .cpu_usage_nsec
= (uint64_t) -1,
4405 .tasks_current
= (uint64_t) -1,
4406 .tasks_max
= (uint64_t) -1,
4414 log_debug("Showing one %s", path
);
4416 r
= sd_bus_call_method(
4418 "org.freedesktop.systemd1",
4420 "org.freedesktop.DBus.Properties",
4426 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4428 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4430 return bus_log_parse_error(r
);
4437 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4438 const char *name
, *contents
;
4440 r
= sd_bus_message_read(reply
, "s", &name
);
4442 return bus_log_parse_error(r
);
4444 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4446 return bus_log_parse_error(r
);
4448 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4450 return bus_log_parse_error(r
);
4452 if (show_properties
)
4453 r
= print_property(name
, reply
, contents
);
4455 r
= status_property(name
, reply
, &info
, contents
);
4459 r
= sd_bus_message_exit_container(reply
);
4461 return bus_log_parse_error(r
);
4463 r
= sd_bus_message_exit_container(reply
);
4465 return bus_log_parse_error(r
);
4468 return bus_log_parse_error(r
);
4470 r
= sd_bus_message_exit_container(reply
);
4472 return bus_log_parse_error(r
);
4476 if (!show_properties
) {
4477 if (streq(verb
, "help"))
4478 show_unit_help(&info
);
4480 print_status_info(&info
, ellipsized
);
4483 strv_free(info
.documentation
);
4484 strv_free(info
.dropin_paths
);
4485 strv_free(info
.listen
);
4487 if (!streq_ptr(info
.active_state
, "active") &&
4488 !streq_ptr(info
.active_state
, "reloading") &&
4489 streq(verb
, "status")) {
4490 /* According to LSB: "program not running" */
4491 /* 0: program is running or service is OK
4492 * 1: program is dead and /run PID file exists
4493 * 2: program is dead and /run/lock lock file exists
4494 * 3: program is not running
4495 * 4: program or service status is unknown
4497 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4503 while ((p
= info
.exec
)) {
4504 LIST_REMOVE(exec
, info
.exec
, p
);
4505 exec_status_info_free(p
);
4511 static int get_unit_dbus_path_by_pid(
4516 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4517 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4521 r
= sd_bus_call_method(
4523 "org.freedesktop.systemd1",
4524 "/org/freedesktop/systemd1",
4525 "org.freedesktop.systemd1.Manager",
4531 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4533 r
= sd_bus_message_read(reply
, "o", &u
);
4535 return bus_log_parse_error(r
);
4545 static int show_all(
4548 bool show_properties
,
4552 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4553 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4558 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4562 pager_open_if_enabled();
4566 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4568 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4569 _cleanup_free_
char *p
= NULL
;
4571 p
= unit_dbus_path_from_name(u
->id
);
4575 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4578 else if (r
> 0 && ret
== 0)
4585 static int show_system_status(sd_bus
*bus
) {
4586 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4587 _cleanup_free_
char *hn
= NULL
;
4588 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4589 const char *on
, *off
;
4592 hn
= gethostname_malloc();
4596 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4598 return log_error_errno(r
, "Failed to read server status: %m");
4600 if (streq_ptr(mi
.state
, "degraded")) {
4601 on
= ansi_highlight_red();
4602 off
= ansi_normal();
4603 } else if (!streq_ptr(mi
.state
, "running")) {
4604 on
= ansi_highlight_yellow();
4605 off
= ansi_normal();
4609 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4611 printf(" State: %s%s%s\n",
4612 on
, strna(mi
.state
), off
);
4614 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4615 printf(" Failed: %u units\n", mi
.n_failed_units
);
4617 printf(" Since: %s; %s\n",
4618 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4619 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4621 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4622 if (IN_SET(arg_transport
,
4623 BUS_TRANSPORT_LOCAL
,
4624 BUS_TRANSPORT_MACHINE
)) {
4625 static const char prefix
[] = " ";
4629 if (c
> sizeof(prefix
) - 1)
4630 c
-= sizeof(prefix
) - 1;
4634 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4640 static int show(int argc
, char *argv
[], void *userdata
) {
4641 bool show_properties
, show_status
, show_help
, new_line
= false;
4642 bool ellipsized
= false;
4648 show_properties
= streq(argv
[0], "show");
4649 show_status
= streq(argv
[0], "status");
4650 show_help
= streq(argv
[0], "help");
4652 if (show_help
&& argc
<= 1) {
4653 log_error("This command expects one or more unit names. Did you mean --help?");
4657 pager_open_if_enabled();
4660 /* Increase max number of open files to 16K if we can, we
4661 * might needs this when browsing journal files, which might
4662 * be split up into many files. */
4663 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4665 r
= acquire_bus(BUS_MANAGER
, &bus
);
4669 /* If no argument is specified inspect the manager itself */
4670 if (show_properties
&& argc
<= 1)
4671 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4673 if (show_status
&& argc
<= 1) {
4675 pager_open_if_enabled();
4676 show_system_status(bus
);
4680 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4682 _cleanup_free_
char **patterns
= NULL
;
4685 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4686 _cleanup_free_
char *unit
= NULL
;
4689 if (safe_atou32(*name
, &id
) < 0) {
4690 if (strv_push(&patterns
, *name
) < 0)
4694 } else if (show_properties
) {
4695 /* Interpret as job id */
4696 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4700 /* Interpret as PID */
4701 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4708 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4711 else if (r
> 0 && ret
== 0)
4715 if (!strv_isempty(patterns
)) {
4716 _cleanup_strv_free_
char **names
= NULL
;
4718 r
= expand_names(bus
, patterns
, NULL
, &names
);
4720 return log_error_errno(r
, "Failed to expand names: %m");
4722 STRV_FOREACH(name
, names
) {
4723 _cleanup_free_
char *unit
;
4725 unit
= unit_dbus_path_from_name(*name
);
4729 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4732 else if (r
> 0 && ret
== 0)
4738 if (ellipsized
&& !arg_quiet
)
4739 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4744 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4748 assert(user_runtime
);
4751 if (arg_scope
== UNIT_FILE_USER
) {
4752 r
= user_config_home(user_home
);
4754 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4756 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4758 r
= user_runtime_dir(user_runtime
);
4760 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4762 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4765 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4767 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4772 static int cat_file(const char *filename
, bool newline
) {
4773 _cleanup_close_
int fd
;
4775 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4779 printf("%s%s# %s%s\n",
4780 newline
? "\n" : "",
4781 ansi_highlight_blue(),
4786 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4789 static int cat(int argc
, char *argv
[], void *userdata
) {
4790 _cleanup_free_
char *user_home
= NULL
;
4791 _cleanup_free_
char *user_runtime
= NULL
;
4792 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4793 _cleanup_strv_free_
char **names
= NULL
;
4799 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4800 log_error("Cannot remotely cat units.");
4804 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4808 r
= acquire_bus(BUS_MANAGER
, &bus
);
4812 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4814 return log_error_errno(r
, "Failed to expand names: %m");
4816 pager_open_if_enabled();
4818 STRV_FOREACH(name
, names
) {
4819 _cleanup_free_
char *fragment_path
= NULL
;
4820 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4823 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4834 if (fragment_path
) {
4835 r
= cat_file(fragment_path
, false);
4837 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4840 STRV_FOREACH(path
, dropin_paths
) {
4841 r
= cat_file(*path
, path
== dropin_paths
);
4843 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4850 static int set_property(int argc
, char *argv
[], void *userdata
) {
4851 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4852 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4853 _cleanup_free_
char *n
= NULL
;
4858 polkit_agent_open_if_enabled();
4860 r
= acquire_bus(BUS_MANAGER
, &bus
);
4864 r
= sd_bus_message_new_method_call(
4867 "org.freedesktop.systemd1",
4868 "/org/freedesktop/systemd1",
4869 "org.freedesktop.systemd1.Manager",
4870 "SetUnitProperties");
4872 return bus_log_create_error(r
);
4874 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4876 return log_error_errno(r
, "Failed to mangle unit name: %m");
4878 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4880 return bus_log_create_error(r
);
4882 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4884 return bus_log_create_error(r
);
4886 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4887 r
= bus_append_unit_property_assignment(m
, *i
);
4892 r
= sd_bus_message_close_container(m
);
4894 return bus_log_create_error(r
);
4896 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4898 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4903 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4904 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4909 polkit_agent_open_if_enabled();
4911 r
= acquire_bus(BUS_MANAGER
, &bus
);
4915 if (arg_action
== ACTION_RELOAD
)
4917 else if (arg_action
== ACTION_REEXEC
)
4918 method
= "Reexecute";
4920 assert(arg_action
== ACTION_SYSTEMCTL
);
4923 streq(argv
[0], "clear-jobs") ||
4924 streq(argv
[0], "cancel") ? "ClearJobs" :
4925 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4926 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4927 streq(argv
[0], "halt") ? "Halt" :
4928 streq(argv
[0], "poweroff") ? "PowerOff" :
4929 streq(argv
[0], "reboot") ? "Reboot" :
4930 streq(argv
[0], "kexec") ? "KExec" :
4931 streq(argv
[0], "exit") ? "Exit" :
4932 /* "daemon-reload" */ "Reload";
4935 r
= sd_bus_call_method(
4937 "org.freedesktop.systemd1",
4938 "/org/freedesktop/systemd1",
4939 "org.freedesktop.systemd1.Manager",
4944 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4945 /* There's always a fallback possible for
4946 * legacy actions. */
4948 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4949 /* On reexecution, we expect a disconnect, not a
4953 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
4955 return r
< 0 ? r
: 0;
4958 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4959 _cleanup_strv_free_
char **names
= NULL
;
4965 return daemon_reload(argc
, argv
, userdata
);
4967 polkit_agent_open_if_enabled();
4969 r
= acquire_bus(BUS_MANAGER
, &bus
);
4973 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4975 return log_error_errno(r
, "Failed to expand names: %m");
4977 STRV_FOREACH(name
, names
) {
4978 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4980 q
= sd_bus_call_method(
4982 "org.freedesktop.systemd1",
4983 "/org/freedesktop/systemd1",
4984 "org.freedesktop.systemd1.Manager",
4990 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4999 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5000 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5001 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5006 pager_open_if_enabled();
5008 r
= acquire_bus(BUS_MANAGER
, &bus
);
5012 r
= sd_bus_get_property(
5014 "org.freedesktop.systemd1",
5015 "/org/freedesktop/systemd1",
5016 "org.freedesktop.systemd1.Manager",
5022 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5024 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5026 return bus_log_parse_error(r
);
5028 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5031 return bus_log_parse_error(r
);
5033 r
= sd_bus_message_exit_container(reply
);
5035 return bus_log_parse_error(r
);
5040 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5041 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5042 _cleanup_free_
char *cmdline_init
= NULL
;
5043 const char *root
, *init
;
5047 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5048 log_error("Cannot switch root remotely.");
5052 if (argc
< 2 || argc
> 3) {
5053 log_error("Wrong number of arguments.");
5062 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5063 "init", &cmdline_init
,
5066 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5068 init
= cmdline_init
;
5075 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5077 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5078 root_init_path
= strjoina(root
, "/", init
);
5080 /* If the passed init is actually the same as the
5081 * systemd binary, then let's suppress it. */
5082 if (files_same(root_init_path
, root_systemd_path
) > 0)
5086 r
= acquire_bus(BUS_MANAGER
, &bus
);
5090 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5092 r
= sd_bus_call_method(
5094 "org.freedesktop.systemd1",
5095 "/org/freedesktop/systemd1",
5096 "org.freedesktop.systemd1.Manager",
5102 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5107 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5108 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5109 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5117 polkit_agent_open_if_enabled();
5119 r
= acquire_bus(BUS_MANAGER
, &bus
);
5123 method
= streq(argv
[0], "set-environment")
5125 : "UnsetEnvironment";
5127 r
= sd_bus_message_new_method_call(
5130 "org.freedesktop.systemd1",
5131 "/org/freedesktop/systemd1",
5132 "org.freedesktop.systemd1.Manager",
5135 return bus_log_create_error(r
);
5137 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5139 return bus_log_create_error(r
);
5141 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5143 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5148 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5149 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5150 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5154 polkit_agent_open_if_enabled();
5156 r
= acquire_bus(BUS_MANAGER
, &bus
);
5160 r
= sd_bus_message_new_method_call(
5163 "org.freedesktop.systemd1",
5164 "/org/freedesktop/systemd1",
5165 "org.freedesktop.systemd1.Manager",
5168 return bus_log_create_error(r
);
5171 r
= sd_bus_message_append_strv(m
, environ
);
5175 r
= sd_bus_message_open_container(m
, 'a', "s");
5177 return bus_log_create_error(r
);
5179 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5181 if (!env_name_is_valid(*a
)) {
5182 log_error("Not a valid environment variable name: %s", *a
);
5186 STRV_FOREACH(b
, environ
) {
5189 eq
= startswith(*b
, *a
);
5190 if (eq
&& *eq
== '=') {
5192 r
= sd_bus_message_append(m
, "s", *b
);
5194 return bus_log_create_error(r
);
5201 r
= sd_bus_message_close_container(m
);
5204 return bus_log_create_error(r
);
5206 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5208 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5213 static int enable_sysv_units(const char *verb
, char **args
) {
5216 #if defined(HAVE_SYSV_COMPAT)
5218 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5220 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5223 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5226 if (!STR_IN_SET(verb
,
5232 /* Processes all SysV units, and reshuffles the array so that
5233 * afterwards only the native units remain */
5235 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5242 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5243 bool found_native
= false, found_sysv
;
5245 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5253 if (!endswith(name
, ".service"))
5256 if (path_is_absolute(name
))
5259 STRV_FOREACH(k
, paths
.unit_path
) {
5260 _cleanup_free_
char *path
= NULL
;
5262 path
= path_join(arg_root
, *k
, name
);
5266 found_native
= access(path
, F_OK
) >= 0;
5271 /* If we have both a native unit and a SysV script,
5272 * enable/disable them both (below); for is-enabled, prefer the
5274 if (found_native
&& streq(verb
, "is-enabled"))
5277 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5281 p
[strlen(p
) - strlen(".service")] = 0;
5282 found_sysv
= access(p
, F_OK
) >= 0;
5287 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5289 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5291 if (!isempty(arg_root
))
5292 argv
[c
++] = q
= strappend("--root=", arg_root
);
5295 argv
[c
++] = basename(p
);
5298 l
= strv_join((char**)argv
, " ");
5302 log_info("Executing %s", l
);
5306 return log_error_errno(errno
, "Failed to fork: %m");
5307 else if (pid
== 0) {
5310 (void) reset_all_signal_handlers();
5311 (void) reset_signal_mask();
5313 execv(argv
[0], (char**) argv
);
5314 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5315 _exit(EXIT_FAILURE
);
5318 j
= wait_for_terminate(pid
, &status
);
5320 log_error_errno(j
, "Failed to wait for child: %m");
5324 if (status
.si_code
== CLD_EXITED
) {
5325 if (streq(verb
, "is-enabled")) {
5326 if (status
.si_status
== 0) {
5335 } else if (status
.si_status
!= 0)
5343 /* Remove this entry, so that we don't try enabling it as native unit */
5346 assert(args
[f
] == name
);
5347 strv_remove(args
, name
);
5354 static int mangle_names(char **original_names
, char ***mangled_names
) {
5355 char **i
, **l
, **name
;
5358 l
= i
= new(char*, strv_length(original_names
) + 1);
5362 STRV_FOREACH(name
, original_names
) {
5364 /* When enabling units qualified path names are OK,
5365 * too, hence allow them explicitly. */
5367 if (is_path(*name
)) {
5374 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5377 return log_error_errno(r
, "Failed to mangle unit name: %m");
5390 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5391 _cleanup_strv_free_
char **names
= NULL
;
5392 const char *verb
= argv
[0];
5393 UnitFileChange
*changes
= NULL
;
5394 unsigned n_changes
= 0;
5395 int carries_install_info
= -1;
5401 r
= mangle_names(strv_skip(argv
, 1), &names
);
5405 r
= enable_sysv_units(verb
, names
);
5409 /* If the operation was fully executed by the SysV compat,
5410 * let's finish early */
5411 if (strv_isempty(names
))
5414 if (install_client_side()) {
5415 if (streq(verb
, "enable")) {
5416 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5417 carries_install_info
= r
;
5418 } else if (streq(verb
, "disable"))
5419 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5420 else if (streq(verb
, "reenable")) {
5421 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5422 carries_install_info
= r
;
5423 } else if (streq(verb
, "link"))
5424 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5425 else if (streq(verb
, "preset")) {
5426 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5427 carries_install_info
= r
;
5428 } else if (streq(verb
, "mask"))
5429 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5430 else if (streq(verb
, "unmask"))
5431 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5433 assert_not_reached("Unknown verb");
5435 if (r
== -ESHUTDOWN
)
5436 return log_error_errno(r
, "Unit file is masked.");
5438 return log_error_errno(r
, "Operation failed: %m");
5441 dump_unit_file_changes(changes
, n_changes
);
5445 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5446 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5447 int expect_carries_install_info
= false;
5448 bool send_force
= true, send_preset_mode
= false;
5452 polkit_agent_open_if_enabled();
5454 r
= acquire_bus(BUS_MANAGER
, &bus
);
5458 if (streq(verb
, "enable")) {
5459 method
= "EnableUnitFiles";
5460 expect_carries_install_info
= true;
5461 } else if (streq(verb
, "disable")) {
5462 method
= "DisableUnitFiles";
5464 } else if (streq(verb
, "reenable")) {
5465 method
= "ReenableUnitFiles";
5466 expect_carries_install_info
= true;
5467 } else if (streq(verb
, "link"))
5468 method
= "LinkUnitFiles";
5469 else if (streq(verb
, "preset")) {
5471 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5472 method
= "PresetUnitFilesWithMode";
5473 send_preset_mode
= true;
5475 method
= "PresetUnitFiles";
5477 expect_carries_install_info
= true;
5478 } else if (streq(verb
, "mask"))
5479 method
= "MaskUnitFiles";
5480 else if (streq(verb
, "unmask")) {
5481 method
= "UnmaskUnitFiles";
5484 assert_not_reached("Unknown verb");
5486 r
= sd_bus_message_new_method_call(
5489 "org.freedesktop.systemd1",
5490 "/org/freedesktop/systemd1",
5491 "org.freedesktop.systemd1.Manager",
5494 return bus_log_create_error(r
);
5496 r
= sd_bus_message_append_strv(m
, names
);
5498 return bus_log_create_error(r
);
5500 if (send_preset_mode
) {
5501 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5503 return bus_log_create_error(r
);
5506 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5508 return bus_log_create_error(r
);
5511 r
= sd_bus_message_append(m
, "b", arg_force
);
5513 return bus_log_create_error(r
);
5516 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5518 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5520 if (expect_carries_install_info
) {
5521 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5523 return bus_log_parse_error(r
);
5526 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5530 /* Try to reload if enabled */
5532 r
= daemon_reload(argc
, argv
, userdata
);
5537 if (carries_install_info
== 0)
5538 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5539 "using systemctl.\n"
5540 "Possible reasons for having this kind of units are:\n"
5541 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5542 " .wants/ or .requires/ directory.\n"
5543 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5544 " a requirement dependency on it.\n"
5545 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5546 " D-Bus, udev, scripted systemctl call, ...).\n");
5548 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5549 char *new_args
[n_changes
+ 2];
5553 r
= acquire_bus(BUS_MANAGER
, &bus
);
5557 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5558 for (i
= 0; i
< n_changes
; i
++)
5559 new_args
[i
+ 1] = basename(changes
[i
].path
);
5560 new_args
[i
+ 1] = NULL
;
5562 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5566 unit_file_changes_free(changes
, n_changes
);
5571 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5572 _cleanup_strv_free_
char **names
= NULL
;
5573 _cleanup_free_
char *target
= NULL
;
5574 const char *verb
= argv
[0];
5581 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5583 return log_error_errno(r
, "Failed to mangle unit name: %m");
5585 r
= mangle_names(strv_skip(argv
, 2), &names
);
5589 if (streq(verb
, "add-wants"))
5591 else if (streq(verb
, "add-requires"))
5592 dep
= UNIT_REQUIRES
;
5594 assert_not_reached("Unknown verb");
5596 if (install_client_side()) {
5597 UnitFileChange
*changes
= NULL
;
5598 unsigned n_changes
= 0;
5600 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5601 if (r
== -ESHUTDOWN
)
5602 return log_error_errno(r
, "Unit file is masked.");
5604 return log_error_errno(r
, "Can't add dependency: %m");
5607 dump_unit_file_changes(changes
, n_changes
);
5609 unit_file_changes_free(changes
, n_changes
);
5612 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5613 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5616 polkit_agent_open_if_enabled();
5618 r
= acquire_bus(BUS_MANAGER
, &bus
);
5622 r
= sd_bus_message_new_method_call(
5625 "org.freedesktop.systemd1",
5626 "/org/freedesktop/systemd1",
5627 "org.freedesktop.systemd1.Manager",
5628 "AddDependencyUnitFiles");
5630 return bus_log_create_error(r
);
5632 r
= sd_bus_message_append_strv(m
, names
);
5634 return bus_log_create_error(r
);
5636 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5638 return bus_log_create_error(r
);
5640 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5642 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5644 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5649 r
= daemon_reload(argc
, argv
, userdata
);
5657 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5658 UnitFileChange
*changes
= NULL
;
5659 unsigned n_changes
= 0;
5662 if (install_client_side()) {
5664 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5666 log_error_errno(r
, "Operation failed: %m");
5671 dump_unit_file_changes(changes
, n_changes
);
5676 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5677 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5680 polkit_agent_open_if_enabled();
5682 r
= acquire_bus(BUS_MANAGER
, &bus
);
5686 r
= sd_bus_call_method(
5688 "org.freedesktop.systemd1",
5689 "/org/freedesktop/systemd1",
5690 "org.freedesktop.systemd1.Manager",
5691 "PresetAllUnitFiles",
5695 unit_file_preset_mode_to_string(arg_preset_mode
),
5699 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5701 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5706 r
= daemon_reload(argc
, argv
, userdata
);
5712 unit_file_changes_free(changes
, n_changes
);
5717 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5719 _cleanup_strv_free_
char **names
= NULL
;
5724 r
= mangle_names(strv_skip(argv
, 1), &names
);
5728 r
= enable_sysv_units(argv
[0], names
);
5734 if (install_client_side()) {
5736 STRV_FOREACH(name
, names
) {
5737 UnitFileState state
;
5739 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5741 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5745 UNIT_FILE_ENABLED_RUNTIME
,
5747 UNIT_FILE_INDIRECT
))
5751 puts(unit_file_state_to_string(state
));
5755 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5758 r
= acquire_bus(BUS_MANAGER
, &bus
);
5762 STRV_FOREACH(name
, names
) {
5763 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5766 r
= sd_bus_call_method(
5768 "org.freedesktop.systemd1",
5769 "/org/freedesktop/systemd1",
5770 "org.freedesktop.systemd1.Manager",
5776 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5778 r
= sd_bus_message_read(reply
, "s", &s
);
5780 return bus_log_parse_error(r
);
5782 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5793 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5794 _cleanup_free_
char *state
= NULL
;
5798 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5801 return EXIT_FAILURE
;
5804 r
= acquire_bus(BUS_MANAGER
, &bus
);
5808 r
= sd_bus_get_property_string(
5810 "org.freedesktop.systemd1",
5811 "/org/freedesktop/systemd1",
5812 "org.freedesktop.systemd1.Manager",
5825 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5828 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5829 _cleanup_free_
char *t
= NULL
;
5833 assert(original_path
);
5836 r
= tempfn_random(new_path
, NULL
, &t
);
5838 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5840 r
= mkdir_parents(new_path
, 0755);
5842 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5844 r
= copy_file(original_path
, t
, 0, 0644, 0);
5849 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5852 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5860 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5861 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5866 switch (arg_scope
) {
5867 case UNIT_FILE_SYSTEM
:
5868 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5870 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5872 case UNIT_FILE_GLOBAL
:
5873 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5875 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5877 case UNIT_FILE_USER
:
5879 assert(user_runtime
);
5881 path
= path_join(arg_root
, user_home
, name
);
5883 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5886 run
= path_join(arg_root
, user_runtime
, name
);
5890 assert_not_reached("Invalid scope");
5892 if (!path
|| (arg_runtime
&& !run
))
5896 if (access(path
, F_OK
) >= 0) {
5897 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5901 if (path2
&& access(path2
, F_OK
) >= 0) {
5902 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5916 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
) {
5917 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5921 assert(ret_new_path
);
5922 assert(ret_tmp_path
);
5924 ending
= strjoina(unit_name
, ".d/override.conf");
5925 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5929 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5935 *ret_new_path
= tmp_new_path
;
5936 *ret_tmp_path
= tmp_tmp_path
;
5941 static int unit_file_create_copy(
5942 const char *unit_name
,
5943 const char *fragment_path
,
5944 const char *user_home
,
5945 const char *user_runtime
,
5946 char **ret_new_path
,
5947 char **ret_tmp_path
) {
5949 char *tmp_new_path
, *tmp_tmp_path
;
5952 assert(fragment_path
);
5954 assert(ret_new_path
);
5955 assert(ret_tmp_path
);
5957 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5961 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5964 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5969 if (response
!= 'y') {
5970 log_warning("%s ignored", unit_name
);
5976 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5978 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5983 *ret_new_path
= tmp_new_path
;
5984 *ret_tmp_path
= tmp_tmp_path
;
5989 static int run_editor(char **paths
) {
5997 return log_error_errno(errno
, "Failed to fork: %m");
6001 char *editor
, **editor_args
= NULL
;
6002 char **tmp_path
, **original_path
, *p
;
6003 unsigned n_editor_args
= 0, i
= 1;
6006 (void) reset_all_signal_handlers();
6007 (void) reset_signal_mask();
6009 argc
= strv_length(paths
)/2 + 1;
6011 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6012 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6013 * we try to execute well known editors
6015 editor
= getenv("SYSTEMD_EDITOR");
6017 editor
= getenv("EDITOR");
6019 editor
= getenv("VISUAL");
6021 if (!isempty(editor
)) {
6022 editor_args
= strv_split(editor
, WHITESPACE
);
6025 _exit(EXIT_FAILURE
);
6027 n_editor_args
= strv_length(editor_args
);
6028 argc
+= n_editor_args
- 1;
6030 args
= newa(const char*, argc
+ 1);
6032 if (n_editor_args
> 0) {
6033 args
[0] = editor_args
[0];
6034 for (; i
< n_editor_args
; i
++)
6035 args
[i
] = editor_args
[i
];
6038 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6039 args
[i
] = *tmp_path
;
6044 if (n_editor_args
> 0)
6045 execvp(args
[0], (char* const*) args
);
6047 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6049 execvp(p
, (char* const*) args
);
6050 /* We do not fail if the editor doesn't exist
6051 * because we want to try each one of them before
6054 if (errno
!= ENOENT
) {
6055 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6056 _exit(EXIT_FAILURE
);
6060 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6061 _exit(EXIT_FAILURE
);
6064 r
= wait_for_terminate_and_warn("editor", pid
, true);
6066 return log_error_errno(r
, "Failed to wait for child: %m");
6071 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6072 _cleanup_free_
char *user_home
= NULL
;
6073 _cleanup_free_
char *user_runtime
= NULL
;
6074 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6081 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6085 STRV_FOREACH(name
, names
) {
6086 _cleanup_free_
char *path
= NULL
;
6087 char *new_path
, *tmp_path
;
6089 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6095 // FIXME: support units with path==NULL (no FragmentPath)
6096 log_error("No fragment exists for %s.", *name
);
6101 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6103 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6107 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6115 static int edit(int argc
, char *argv
[], void *userdata
) {
6116 _cleanup_strv_free_
char **names
= NULL
;
6117 _cleanup_strv_free_
char **paths
= NULL
;
6118 char **original
, **tmp
;
6123 log_error("Cannot edit units if not on a tty.");
6127 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6128 log_error("Cannot edit units remotely.");
6132 r
= acquire_bus(BUS_MANAGER
, &bus
);
6136 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6138 return log_error_errno(r
, "Failed to expand names: %m");
6140 r
= find_paths_to_edit(bus
, names
, &paths
);
6144 if (strv_isempty(paths
))
6147 r
= run_editor(paths
);
6151 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6152 /* If the temporary file is empty we ignore it. It's
6153 * useful if the user wants to cancel its modification
6155 if (null_or_empty_path(*tmp
)) {
6156 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6160 r
= rename(*tmp
, *original
);
6162 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6169 if (!arg_no_reload
&& !install_client_side())
6170 r
= daemon_reload(argc
, argv
, userdata
);
6173 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6174 (void) unlink(*tmp
);
6179 static void systemctl_help(void) {
6181 pager_open_if_enabled();
6183 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6184 "Query or send control commands to the systemd manager.\n\n"
6185 " -h --help Show this help\n"
6186 " --version Show package version\n"
6187 " --system Connect to system manager\n"
6188 " --user Connect to user service manager\n"
6189 " -H --host=[USER@]HOST\n"
6190 " Operate on remote host\n"
6191 " -M --machine=CONTAINER\n"
6192 " Operate on local container\n"
6193 " -t --type=TYPE List units of a particular type\n"
6194 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6195 " -p --property=NAME Show only properties by this name\n"
6196 " -a --all Show all loaded units/properties, including dead/empty\n"
6197 " ones. To list all units installed on the system, use\n"
6198 " the 'list-unit-files' command instead.\n"
6199 " -l --full Don't ellipsize unit names on output\n"
6200 " -r --recursive Show unit list of host and local containers\n"
6201 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6202 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6203 " queueing a new job\n"
6204 " --show-types When showing sockets, explicitly show their type\n"
6205 " -i --ignore-inhibitors\n"
6206 " When shutting down or sleeping, ignore inhibitors\n"
6207 " --kill-who=WHO Who to send signal to\n"
6208 " -s --signal=SIGNAL Which signal to send\n"
6209 " --now Start or stop unit in addition to enabling or disabling it\n"
6210 " -q --quiet Suppress output\n"
6211 " --no-block Do not wait until operation finished\n"
6212 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6213 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6214 " --no-legend Do not print a legend (column headers and hints)\n"
6215 " --no-pager Do not pipe output into a pager\n"
6216 " --no-ask-password\n"
6217 " Do not ask for system passwords\n"
6218 " --global Enable/disable unit files globally\n"
6219 " --runtime Enable unit files only temporarily until next reboot\n"
6220 " -f --force When enabling unit files, override existing symlinks\n"
6221 " When shutting down, execute action immediately\n"
6222 " --preset-mode= Apply only enable, only disable, or all presets\n"
6223 " --root=PATH Enable unit files in the specified root directory\n"
6224 " -n --lines=INTEGER Number of journal entries to show\n"
6225 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6226 " short-precise, short-monotonic, verbose,\n"
6227 " export, json, json-pretty, json-sse, cat)\n"
6228 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6229 " --plain Print unit dependencies as a list instead of a tree\n\n"
6231 " list-units [PATTERN...] List loaded units\n"
6232 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6233 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6234 " start NAME... Start (activate) one or more units\n"
6235 " stop NAME... Stop (deactivate) one or more units\n"
6236 " reload NAME... Reload one or more units\n"
6237 " restart NAME... Start or restart one or more units\n"
6238 " try-restart NAME... Restart one or more units if active\n"
6239 " reload-or-restart NAME... Reload one or more units if possible,\n"
6240 " otherwise start or restart\n"
6241 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6242 " if supported, otherwise restart\n"
6243 " isolate NAME Start one unit and stop all others\n"
6244 " kill NAME... Send signal to processes of a unit\n"
6245 " is-active PATTERN... Check whether units are active\n"
6246 " is-failed PATTERN... Check whether units are failed\n"
6247 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6248 " show [PATTERN...|JOB...] Show properties of one or more\n"
6249 " units/jobs or the manager\n"
6250 " cat PATTERN... Show files and drop-ins of one or more units\n"
6251 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6252 " help PATTERN...|PID... Show manual for one or more units\n"
6253 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6255 " list-dependencies [NAME] Recursively show units which are required\n"
6256 " or wanted by this unit or by which this\n"
6257 " unit is required or wanted\n\n"
6258 "Unit File Commands:\n"
6259 " list-unit-files [PATTERN...] List installed unit files\n"
6260 " enable NAME... Enable one or more unit files\n"
6261 " disable NAME... Disable one or more unit files\n"
6262 " reenable NAME... Reenable one or more unit files\n"
6263 " preset NAME... Enable/disable one or more unit files\n"
6264 " based on preset configuration\n"
6265 " preset-all Enable/disable all unit files based on\n"
6266 " preset configuration\n"
6267 " is-enabled NAME... Check whether unit files are enabled\n"
6268 " mask NAME... Mask one or more units\n"
6269 " unmask NAME... Unmask one or more units\n"
6270 " link PATH... Link one or more units files into\n"
6271 " the search path\n"
6272 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6273 " on specified one or more units\n"
6274 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6275 " on specified one or more units\n"
6276 " edit NAME... Edit one or more unit files\n"
6277 " get-default Get the name of the default target\n"
6278 " set-default NAME Set the default target\n\n"
6279 "Machine Commands:\n"
6280 " list-machines [PATTERN...] List local containers and host\n\n"
6282 " list-jobs [PATTERN...] List jobs\n"
6283 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6284 "Environment Commands:\n"
6285 " show-environment Dump environment\n"
6286 " set-environment NAME=VALUE... Set one or more environment variables\n"
6287 " unset-environment NAME... Unset one or more environment variables\n"
6288 " import-environment [NAME...] Import all or some environment variables\n\n"
6289 "Manager Lifecycle Commands:\n"
6290 " daemon-reload Reload systemd manager configuration\n"
6291 " daemon-reexec Reexecute systemd manager\n\n"
6292 "System Commands:\n"
6293 " is-system-running Check whether system is fully running\n"
6294 " default Enter system default mode\n"
6295 " rescue Enter system rescue mode\n"
6296 " emergency Enter system emergency mode\n"
6297 " halt Shut down and halt the system\n"
6298 " poweroff Shut down and power-off the system\n"
6299 " reboot [ARG] Shut down and reboot the system\n"
6300 " kexec Shut down and reboot the system with kexec\n"
6301 " exit [EXIT_CODE] Request user instance or container exit\n"
6302 " switch-root ROOT [INIT] Change to a different root file system\n"
6303 " suspend Suspend the system\n"
6304 " hibernate Hibernate the system\n"
6305 " hybrid-sleep Hibernate and suspend the system\n",
6306 program_invocation_short_name
);
6309 static void halt_help(void) {
6310 printf("%s [OPTIONS...]%s\n\n"
6311 "%s the system.\n\n"
6312 " --help Show this help\n"
6313 " --halt Halt the machine\n"
6314 " -p --poweroff Switch off the machine\n"
6315 " --reboot Reboot the machine\n"
6316 " -f --force Force immediate halt/power-off/reboot\n"
6317 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6318 " -d --no-wtmp Don't write wtmp record\n"
6319 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6320 program_invocation_short_name
,
6321 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6322 arg_action
== ACTION_REBOOT
? "Reboot" :
6323 arg_action
== ACTION_POWEROFF
? "Power off" :
6327 static void shutdown_help(void) {
6328 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6329 "Shut down the system.\n\n"
6330 " --help Show this help\n"
6331 " -H --halt Halt the machine\n"
6332 " -P --poweroff Power-off the machine\n"
6333 " -r --reboot Reboot the machine\n"
6334 " -h Equivalent to --poweroff, overridden by --halt\n"
6335 " -k Don't halt/power-off/reboot, just send warnings\n"
6336 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6337 " -c Cancel a pending shutdown\n",
6338 program_invocation_short_name
);
6341 static void telinit_help(void) {
6342 printf("%s [OPTIONS...] {COMMAND}\n\n"
6343 "Send control commands to the init daemon.\n\n"
6344 " --help Show this help\n"
6345 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6347 " 0 Power-off the machine\n"
6348 " 6 Reboot the machine\n"
6349 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6350 " 1, s, S Enter rescue mode\n"
6351 " q, Q Reload init daemon configuration\n"
6352 " u, U Reexecute init daemon\n",
6353 program_invocation_short_name
);
6356 static void runlevel_help(void) {
6357 printf("%s [OPTIONS...]\n\n"
6358 "Prints the previous and current runlevel of the init system.\n\n"
6359 " --help Show this help\n",
6360 program_invocation_short_name
);
6363 static void help_types(void) {
6367 puts("Available unit types:");
6368 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6369 puts(unit_type_to_string(i
));
6372 static void help_states(void) {
6376 puts("Available unit load states:");
6377 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6378 puts(unit_load_state_to_string(i
));
6381 puts("\nAvailable unit active states:");
6382 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6383 puts(unit_active_state_to_string(i
));
6386 puts("\nAvailable automount unit substates:");
6387 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6388 puts(automount_state_to_string(i
));
6391 puts("\nAvailable busname unit substates:");
6392 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6393 puts(busname_state_to_string(i
));
6396 puts("\nAvailable device unit substates:");
6397 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6398 puts(device_state_to_string(i
));
6401 puts("\nAvailable mount unit substates:");
6402 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6403 puts(mount_state_to_string(i
));
6406 puts("\nAvailable path unit substates:");
6407 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6408 puts(path_state_to_string(i
));
6411 puts("\nAvailable scope unit substates:");
6412 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6413 puts(scope_state_to_string(i
));
6416 puts("\nAvailable service unit substates:");
6417 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6418 puts(service_state_to_string(i
));
6421 puts("\nAvailable slice unit substates:");
6422 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6423 puts(slice_state_to_string(i
));
6426 puts("\nAvailable socket unit substates:");
6427 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6428 puts(socket_state_to_string(i
));
6431 puts("\nAvailable swap unit substates:");
6432 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6433 puts(swap_state_to_string(i
));
6436 puts("\nAvailable target unit substates:");
6437 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6438 puts(target_state_to_string(i
));
6441 puts("\nAvailable timer unit substates:");
6442 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6443 puts(timer_state_to_string(i
));
6446 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6455 ARG_IGNORE_DEPENDENCIES
,
6467 ARG_NO_ASK_PASSWORD
,
6480 static const struct option options
[] = {
6481 { "help", no_argument
, NULL
, 'h' },
6482 { "version", no_argument
, NULL
, ARG_VERSION
},
6483 { "type", required_argument
, NULL
, 't' },
6484 { "property", required_argument
, NULL
, 'p' },
6485 { "all", no_argument
, NULL
, 'a' },
6486 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6487 { "after", no_argument
, NULL
, ARG_AFTER
},
6488 { "before", no_argument
, NULL
, ARG_BEFORE
},
6489 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6490 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6491 { "full", no_argument
, NULL
, 'l' },
6492 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6493 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6494 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6495 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6496 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6497 { "user", no_argument
, NULL
, ARG_USER
},
6498 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6499 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6500 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6501 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6502 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6503 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6504 { "quiet", no_argument
, NULL
, 'q' },
6505 { "root", required_argument
, NULL
, ARG_ROOT
},
6506 { "force", no_argument
, NULL
, ARG_FORCE
},
6507 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6508 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6509 { "signal", required_argument
, NULL
, 's' },
6510 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6511 { "host", required_argument
, NULL
, 'H' },
6512 { "machine", required_argument
, NULL
, 'M' },
6513 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6514 { "lines", required_argument
, NULL
, 'n' },
6515 { "output", required_argument
, NULL
, 'o' },
6516 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6517 { "state", required_argument
, NULL
, ARG_STATE
},
6518 { "recursive", no_argument
, NULL
, 'r' },
6519 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6520 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6521 { "now", no_argument
, NULL
, ARG_NOW
},
6522 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6532 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6533 arg_ask_password
= true;
6535 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6547 if (isempty(optarg
)) {
6548 log_error("--type requires arguments.");
6554 _cleanup_free_
char *type
= NULL
;
6556 r
= extract_first_word(&p
, &type
, ",", 0);
6558 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6563 if (streq(type
, "help")) {
6568 if (unit_type_from_string(type
) >= 0) {
6569 if (strv_push(&arg_types
, type
) < 0)
6575 /* It's much nicer to use --state= for
6576 * load states, but let's support this
6577 * in --types= too for compatibility
6578 * with old versions */
6579 if (unit_load_state_from_string(type
) >= 0) {
6580 if (strv_push(&arg_states
, type
) < 0)
6586 log_error("Unknown unit type or load state '%s'.", type
);
6587 log_info("Use -t help to see a list of allowed values.");
6595 /* Make sure that if the empty property list
6596 was specified, we won't show any properties. */
6597 if (isempty(optarg
) && !arg_properties
) {
6598 arg_properties
= new0(char*, 1);
6599 if (!arg_properties
)
6604 _cleanup_free_
char *prop
= NULL
;
6606 r
= extract_first_word(&p
, &prop
, ",", 0);
6608 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6613 if (strv_push(&arg_properties
, prop
) < 0)
6620 /* If the user asked for a particular
6621 * property, show it to him, even if it is
6633 arg_dependency
= DEPENDENCY_REVERSE
;
6637 arg_dependency
= DEPENDENCY_AFTER
;
6641 arg_dependency
= DEPENDENCY_BEFORE
;
6644 case ARG_SHOW_TYPES
:
6645 arg_show_types
= true;
6649 arg_job_mode
= optarg
;
6653 arg_job_mode
= "fail";
6656 case ARG_IRREVERSIBLE
:
6657 arg_job_mode
= "replace-irreversibly";
6660 case ARG_IGNORE_DEPENDENCIES
:
6661 arg_job_mode
= "ignore-dependencies";
6665 arg_scope
= UNIT_FILE_USER
;
6669 arg_scope
= UNIT_FILE_SYSTEM
;
6673 arg_scope
= UNIT_FILE_GLOBAL
;
6677 arg_no_block
= true;
6681 arg_no_legend
= true;
6685 arg_no_pager
= true;
6693 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6703 if (strv_extend(&arg_states
, "failed") < 0)
6721 arg_no_reload
= true;
6725 arg_kill_who
= optarg
;
6729 arg_signal
= signal_from_string_try_harder(optarg
);
6730 if (arg_signal
< 0) {
6731 log_error("Failed to parse signal string %s.", optarg
);
6736 case ARG_NO_ASK_PASSWORD
:
6737 arg_ask_password
= false;
6741 arg_transport
= BUS_TRANSPORT_REMOTE
;
6746 arg_transport
= BUS_TRANSPORT_MACHINE
;
6755 if (safe_atou(optarg
, &arg_lines
) < 0) {
6756 log_error("Failed to parse lines '%s'", optarg
);
6762 arg_output
= output_mode_from_string(optarg
);
6763 if (arg_output
< 0) {
6764 log_error("Unknown output '%s'.", optarg
);
6770 arg_ignore_inhibitors
= true;
6777 case ARG_FIRMWARE_SETUP
:
6778 arg_firmware_setup
= true;
6782 if (isempty(optarg
)) {
6783 log_error("--signal requires arguments.");
6789 _cleanup_free_
char *s
= NULL
;
6791 r
= extract_first_word(&p
, &s
, ",", 0);
6793 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6798 if (streq(s
, "help")) {
6803 if (strv_push(&arg_states
, s
) < 0)
6812 if (geteuid() != 0) {
6813 log_error("--recursive requires root privileges.");
6817 arg_recursive
= true;
6820 case ARG_PRESET_MODE
:
6822 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6823 if (arg_preset_mode
< 0) {
6824 log_error("Failed to parse preset mode: %s.", optarg
);
6835 if (strv_extend(&arg_wall
, optarg
) < 0)
6843 assert_not_reached("Unhandled option");
6846 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6847 log_error("Cannot access user instance remotely.");
6854 static int halt_parse_argv(int argc
, char *argv
[]) {
6863 static const struct option options
[] = {
6864 { "help", no_argument
, NULL
, ARG_HELP
},
6865 { "halt", no_argument
, NULL
, ARG_HALT
},
6866 { "poweroff", no_argument
, NULL
, 'p' },
6867 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6868 { "force", no_argument
, NULL
, 'f' },
6869 { "wtmp-only", no_argument
, NULL
, 'w' },
6870 { "no-wtmp", no_argument
, NULL
, 'd' },
6871 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6880 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6881 if (runlevel
== '0' || runlevel
== '6')
6884 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6892 arg_action
= ACTION_HALT
;
6896 if (arg_action
!= ACTION_REBOOT
)
6897 arg_action
= ACTION_POWEROFF
;
6901 arg_action
= ACTION_REBOOT
;
6923 /* Compatibility nops */
6930 assert_not_reached("Unhandled option");
6933 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6934 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6937 } else if (optind
< argc
) {
6938 log_error("Too many arguments.");
6945 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
6949 if (streq(t
, "now"))
6951 else if (!strchr(t
, ':')) {
6954 if (safe_atou64(t
, &u
) < 0)
6957 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6966 hour
= strtol(t
, &e
, 10);
6967 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6970 minute
= strtol(e
+1, &e
, 10);
6971 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6974 n
= now(CLOCK_REALTIME
);
6975 s
= (time_t) (n
/ USEC_PER_SEC
);
6977 assert_se(localtime_r(&s
, &tm
));
6979 tm
.tm_hour
= (int) hour
;
6980 tm
.tm_min
= (int) minute
;
6983 assert_se(s
= mktime(&tm
));
6985 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6988 *_u
+= USEC_PER_DAY
;
6994 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7001 static const struct option options
[] = {
7002 { "help", no_argument
, NULL
, ARG_HELP
},
7003 { "halt", no_argument
, NULL
, 'H' },
7004 { "poweroff", no_argument
, NULL
, 'P' },
7005 { "reboot", no_argument
, NULL
, 'r' },
7006 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7007 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7017 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7025 arg_action
= ACTION_HALT
;
7029 arg_action
= ACTION_POWEROFF
;
7034 arg_action
= ACTION_KEXEC
;
7036 arg_action
= ACTION_REBOOT
;
7040 arg_action
= ACTION_KEXEC
;
7044 if (arg_action
!= ACTION_HALT
)
7045 arg_action
= ACTION_POWEROFF
;
7060 /* Compatibility nops */
7064 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7071 assert_not_reached("Unhandled option");
7074 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7075 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7077 log_error("Failed to parse time specification: %s", argv
[optind
]);
7081 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7083 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7084 /* No time argument for shutdown cancel */
7085 wall
= argv
+ optind
;
7086 else if (argc
> optind
+ 1)
7087 /* We skip the time argument */
7088 wall
= argv
+ optind
+ 1;
7091 arg_wall
= strv_copy(wall
);
7101 static int telinit_parse_argv(int argc
, char *argv
[]) {
7108 static const struct option options
[] = {
7109 { "help", no_argument
, NULL
, ARG_HELP
},
7110 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7114 static const struct {
7118 { '0', ACTION_POWEROFF
},
7119 { '6', ACTION_REBOOT
},
7120 { '1', ACTION_RESCUE
},
7121 { '2', ACTION_RUNLEVEL2
},
7122 { '3', ACTION_RUNLEVEL3
},
7123 { '4', ACTION_RUNLEVEL4
},
7124 { '5', ACTION_RUNLEVEL5
},
7125 { 's', ACTION_RESCUE
},
7126 { 'S', ACTION_RESCUE
},
7127 { 'q', ACTION_RELOAD
},
7128 { 'Q', ACTION_RELOAD
},
7129 { 'u', ACTION_REEXEC
},
7130 { 'U', ACTION_REEXEC
}
7139 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7154 assert_not_reached("Unhandled option");
7157 if (optind
>= argc
) {
7158 log_error("%s: required argument missing.", program_invocation_short_name
);
7162 if (optind
+ 1 < argc
) {
7163 log_error("Too many arguments.");
7167 if (strlen(argv
[optind
]) != 1) {
7168 log_error("Expected single character argument.");
7172 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7173 if (table
[i
].from
== argv
[optind
][0])
7176 if (i
>= ELEMENTSOF(table
)) {
7177 log_error("Unknown command '%s'.", argv
[optind
]);
7181 arg_action
= table
[i
].to
;
7188 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7194 static const struct option options
[] = {
7195 { "help", no_argument
, NULL
, ARG_HELP
},
7204 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7215 assert_not_reached("Unhandled option");
7218 if (optind
< argc
) {
7219 log_error("Too many arguments.");
7226 static int parse_argv(int argc
, char *argv
[]) {
7230 if (program_invocation_short_name
) {
7232 if (strstr(program_invocation_short_name
, "halt")) {
7233 arg_action
= ACTION_HALT
;
7234 return halt_parse_argv(argc
, argv
);
7235 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7236 arg_action
= ACTION_POWEROFF
;
7237 return halt_parse_argv(argc
, argv
);
7238 } else if (strstr(program_invocation_short_name
, "reboot")) {
7240 arg_action
= ACTION_KEXEC
;
7242 arg_action
= ACTION_REBOOT
;
7243 return halt_parse_argv(argc
, argv
);
7244 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7245 arg_action
= ACTION_POWEROFF
;
7246 return shutdown_parse_argv(argc
, argv
);
7247 } else if (strstr(program_invocation_short_name
, "init")) {
7249 if (sd_booted() > 0) {
7250 arg_action
= _ACTION_INVALID
;
7251 return telinit_parse_argv(argc
, argv
);
7253 /* Hmm, so some other init system is
7254 * running, we need to forward this
7255 * request to it. For now we simply
7256 * guess that it is Upstart. */
7258 execv(TELINIT
, argv
);
7260 log_error("Couldn't find an alternative telinit implementation to spawn.");
7264 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7265 arg_action
= ACTION_RUNLEVEL
;
7266 return runlevel_parse_argv(argc
, argv
);
7270 arg_action
= ACTION_SYSTEMCTL
;
7271 return systemctl_parse_argv(argc
, argv
);
7274 _pure_
static int action_to_runlevel(void) {
7276 static const char table
[_ACTION_MAX
] = {
7277 [ACTION_HALT
] = '0',
7278 [ACTION_POWEROFF
] = '0',
7279 [ACTION_REBOOT
] = '6',
7280 [ACTION_RUNLEVEL2
] = '2',
7281 [ACTION_RUNLEVEL3
] = '3',
7282 [ACTION_RUNLEVEL4
] = '4',
7283 [ACTION_RUNLEVEL5
] = '5',
7284 [ACTION_RESCUE
] = '1'
7287 assert(arg_action
< _ACTION_MAX
);
7289 return table
[arg_action
];
7292 static int talk_initctl(void) {
7293 #ifdef HAVE_SYSV_COMPAT
7294 struct init_request request
= {
7295 .magic
= INIT_MAGIC
,
7297 .cmd
= INIT_CMD_RUNLVL
7300 _cleanup_close_
int fd
= -1;
7304 rl
= action_to_runlevel();
7308 request
.runlevel
= rl
;
7310 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7312 if (errno
== ENOENT
)
7315 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7318 r
= loop_write(fd
, &request
, sizeof(request
), false);
7320 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7328 static int systemctl_main(int argc
, char *argv
[]) {
7330 static const Verb verbs
[] = {
7331 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7332 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7333 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7334 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7335 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7336 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7337 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7338 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7339 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7340 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7341 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7342 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7343 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7344 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7345 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7346 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7347 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7348 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7349 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7350 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7351 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7352 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7353 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7354 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7355 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7356 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7357 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7358 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7359 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7360 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7361 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7362 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7363 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7364 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7365 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7366 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7367 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7368 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7369 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7370 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7371 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7372 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7373 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7374 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7375 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7376 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7377 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7378 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7379 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7380 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7381 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7382 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7383 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7384 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7385 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7386 { "link", 2, VERB_ANY
, 0, enable_unit
},
7387 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7388 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7389 { "set-default", 2, 2, 0, set_default
},
7390 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7391 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7392 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7393 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7394 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7395 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7399 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7402 static int reload_with_fallback(void) {
7404 /* First, try systemd via D-Bus. */
7405 if (daemon_reload(0, NULL
, NULL
) >= 0)
7408 /* Nothing else worked, so let's try signals */
7409 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7411 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7412 return log_error_errno(errno
, "kill() failed: %m");
7417 static int start_with_fallback(void) {
7419 /* First, try systemd via D-Bus. */
7420 if (start_unit(0, NULL
, NULL
) >= 0)
7423 /* Nothing else worked, so let's try
7425 if (talk_initctl() > 0)
7428 log_error("Failed to talk to init daemon.");
7432 static int halt_now(enum action a
) {
7434 /* The kernel will automaticall flush ATA disks and suchlike
7435 * on reboot(), but the file systems need to be synce'd
7436 * explicitly in advance. */
7439 /* Make sure C-A-D is handled by the kernel from this point
7441 (void) reboot(RB_ENABLE_CAD
);
7446 log_info("Halting.");
7447 (void) reboot(RB_HALT_SYSTEM
);
7450 case ACTION_POWEROFF
:
7451 log_info("Powering off.");
7452 (void) reboot(RB_POWER_OFF
);
7456 case ACTION_REBOOT
: {
7457 _cleanup_free_
char *param
= NULL
;
7459 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7460 log_info("Rebooting with argument '%s'.", param
);
7461 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7464 log_info("Rebooting.");
7465 (void) reboot(RB_AUTOBOOT
);
7470 assert_not_reached("Unknown action.");
7474 static int logind_schedule_shutdown(void) {
7477 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7478 char date
[FORMAT_TIMESTAMP_MAX
];
7483 (void) logind_set_wall_message();
7485 r
= acquire_bus(BUS_FULL
, &bus
);
7489 switch (arg_action
) {
7493 case ACTION_POWEROFF
:
7494 action
= "poweroff";
7509 action
= strjoina("dry-", action
);
7511 r
= sd_bus_call_method(
7513 "org.freedesktop.login1",
7514 "/org/freedesktop/login1",
7515 "org.freedesktop.login1.Manager",
7523 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7525 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7528 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7533 static int halt_main(void) {
7536 r
= logind_check_inhibitors(arg_action
);
7541 return logind_schedule_shutdown();
7543 if (geteuid() != 0) {
7544 if (arg_dry
|| arg_force
> 0) {
7545 log_error("Must be root.");
7549 /* Try logind if we are a normal user and no special
7550 * mode applies. Maybe PolicyKit allows us to shutdown
7552 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7553 r
= logind_reboot(arg_action
);
7556 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7557 /* requested operation is not
7558 * supported on the local system or
7559 * already in progress */
7561 /* on all other errors, try low-level operation */
7565 if (!arg_dry
&& !arg_force
)
7566 return start_with_fallback();
7568 assert(geteuid() == 0);
7571 if (sd_booted() > 0)
7572 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7574 r
= utmp_put_shutdown();
7576 log_warning_errno(r
, "Failed to write utmp record: %m");
7583 r
= halt_now(arg_action
);
7584 return log_error_errno(r
, "Failed to reboot: %m");
7587 static int runlevel_main(void) {
7588 int r
, runlevel
, previous
;
7590 r
= utmp_get_runlevel(&runlevel
, &previous
);
7597 previous
<= 0 ? 'N' : previous
,
7598 runlevel
<= 0 ? 'N' : runlevel
);
7603 static int logind_cancel_shutdown(void) {
7605 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7609 r
= acquire_bus(BUS_FULL
, &bus
);
7613 (void) logind_set_wall_message();
7615 r
= sd_bus_call_method(
7617 "org.freedesktop.login1",
7618 "/org/freedesktop/login1",
7619 "org.freedesktop.login1.Manager",
7620 "CancelScheduledShutdown",
7624 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7628 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7633 int main(int argc
, char*argv
[]) {
7636 setlocale(LC_ALL
, "");
7637 log_parse_environment();
7640 /* Explicitly not on_tty() to avoid setting cached value.
7641 * This becomes relevant for piping output which might be
7643 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7645 r
= parse_argv(argc
, argv
);
7649 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7650 log_info("Running in chroot, ignoring request.");
7655 /* systemctl_main() will print an error message for the bus
7656 * connection, but only if it needs to */
7658 switch (arg_action
) {
7660 case ACTION_SYSTEMCTL
:
7661 r
= systemctl_main(argc
, argv
);
7665 case ACTION_POWEROFF
:
7671 case ACTION_RUNLEVEL2
:
7672 case ACTION_RUNLEVEL3
:
7673 case ACTION_RUNLEVEL4
:
7674 case ACTION_RUNLEVEL5
:
7676 case ACTION_EMERGENCY
:
7677 case ACTION_DEFAULT
:
7678 r
= start_with_fallback();
7683 r
= reload_with_fallback();
7686 case ACTION_CANCEL_SHUTDOWN
:
7687 r
= logind_cancel_shutdown();
7690 case ACTION_RUNLEVEL
:
7691 r
= runlevel_main();
7694 case _ACTION_INVALID
:
7696 assert_not_reached("Unknown action");
7701 ask_password_agent_close();
7702 polkit_agent_close();
7704 strv_free(arg_types
);
7705 strv_free(arg_states
);
7706 strv_free(arg_properties
);
7708 strv_free(arg_wall
);
7713 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7715 return r
< 0 ? EXIT_FAILURE
: r
;