1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <linux/reboot.h>
32 #include <sys/reboot.h>
33 #include <sys/socket.h>
37 #include "sd-daemon.h"
40 #include "bus-common-errors.h"
41 #include "bus-error.h"
42 #include "bus-message.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
50 #include "exit-status.h"
52 #include "formats-util.h"
53 #include "hostname-util.h"
58 #include "logs-show.h"
62 #include "path-lookup.h"
63 #include "path-util.h"
64 #include "process-util.h"
66 #include "signal-util.h"
67 #include "socket-util.h"
68 #include "spawn-ask-password-agent.h"
69 #include "spawn-polkit-agent.h"
72 #include "terminal-util.h"
73 #include "unit-name.h"
75 #include "utmp-wtmp.h"
78 static char **arg_types
= NULL
;
79 static char **arg_states
= NULL
;
80 static char **arg_properties
= NULL
;
81 static bool arg_all
= false;
82 static enum dependency
{
88 } arg_dependency
= DEPENDENCY_FORWARD
;
89 static const char *arg_job_mode
= "replace";
90 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
91 static bool arg_no_block
= false;
92 static bool arg_no_legend
= false;
93 static bool arg_no_pager
= false;
94 static bool arg_no_wtmp
= false;
95 static bool arg_no_wall
= false;
96 static bool arg_no_reload
= false;
97 static bool arg_show_types
= false;
98 static bool arg_ignore_inhibitors
= false;
99 static bool arg_dry
= false;
100 static bool arg_quiet
= false;
101 static bool arg_full
= false;
102 static bool arg_recursive
= false;
103 static int arg_force
= 0;
104 static bool arg_ask_password
= false;
105 static bool arg_runtime
= false;
106 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
107 static char **arg_wall
= NULL
;
108 static const char *arg_kill_who
= NULL
;
109 static int arg_signal
= SIGTERM
;
110 static const char *arg_root
= NULL
;
111 static usec_t arg_when
= 0;
133 ACTION_CANCEL_SHUTDOWN
,
135 } arg_action
= ACTION_SYSTEMCTL
;
136 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
137 static const char *arg_host
= NULL
;
138 static unsigned arg_lines
= 10;
139 static OutputMode arg_output
= OUTPUT_SHORT
;
140 static bool arg_plain
= false;
141 static bool arg_firmware_setup
= false;
142 static bool arg_now
= false;
144 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
145 static int halt_now(enum action a
);
146 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
148 static bool original_stdout_is_tty
;
150 typedef enum BusFocus
{
151 BUS_FULL
, /* The full bus indicated via --system or --user */
152 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
156 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
158 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
161 assert(focus
< _BUS_FOCUS_MAX
);
164 /* We only go directly to the manager, if we are using a local transport */
165 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
168 if (!busses
[focus
]) {
171 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
173 if (focus
== BUS_MANAGER
)
174 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
176 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
178 return log_error_errno(r
, "Failed to connect to bus: %m");
180 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
183 *ret
= busses
[focus
];
187 static void release_busses(void) {
190 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
191 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
194 static void pager_open_if_enabled(void) {
202 static void ask_password_agent_open_if_enabled(void) {
204 /* Open the password agent as a child process if necessary */
206 if (!arg_ask_password
)
209 if (arg_scope
!= UNIT_FILE_SYSTEM
)
212 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
215 ask_password_agent_open();
218 static void polkit_agent_open_if_enabled(void) {
220 /* Open the polkit agent as a child process if necessary */
222 if (!arg_ask_password
)
225 if (arg_scope
!= UNIT_FILE_SYSTEM
)
228 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
234 static OutputFlags
get_output_flags(void) {
236 arg_all
* OUTPUT_SHOW_ALL
|
237 arg_full
* OUTPUT_FULL_WIDTH
|
238 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
239 on_tty() * OUTPUT_COLOR
|
240 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
243 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
246 if (!sd_bus_error_is_set(error
))
249 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
250 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
251 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
252 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
253 return EXIT_NOPERMISSION
;
255 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
256 return EXIT_NOTINSTALLED
;
258 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
259 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
260 return EXIT_NOTIMPLEMENTED
;
262 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
263 return EXIT_NOTCONFIGURED
;
271 static bool install_client_side(void) {
273 /* Decides when to execute enable/disable/... operations
274 * client-side rather than server-side. */
276 if (running_in_chroot() > 0)
279 if (sd_booted() <= 0)
282 if (!isempty(arg_root
))
285 if (arg_scope
== UNIT_FILE_GLOBAL
)
291 static int compare_unit_info(const void *a
, const void *b
) {
292 const UnitInfo
*u
= a
, *v
= b
;
296 /* First, order by machine */
297 if (!u
->machine
&& v
->machine
)
299 if (u
->machine
&& !v
->machine
)
301 if (u
->machine
&& v
->machine
) {
302 r
= strcasecmp(u
->machine
, v
->machine
);
307 /* Second, order by unit type */
308 d1
= strrchr(u
->id
, '.');
309 d2
= strrchr(v
->id
, '.');
311 r
= strcasecmp(d1
, d2
);
316 /* Third, order by name */
317 return strcasecmp(u
->id
, v
->id
);
320 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
321 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
327 dot
= strrchr(u
->id
, '.');
331 if (!strv_find(arg_types
, dot
+1))
341 if (streq(u
->active_state
, "inactive") || u
->following
[0])
347 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
348 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
350 unsigned n_shown
= 0;
353 max_id_len
= strlen("UNIT");
354 load_len
= strlen("LOAD");
355 active_len
= strlen("ACTIVE");
356 sub_len
= strlen("SUB");
357 job_len
= strlen("JOB");
360 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
361 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
362 load_len
= MAX(load_len
, strlen(u
->load_state
));
363 active_len
= MAX(active_len
, strlen(u
->active_state
));
364 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
366 if (u
->job_id
!= 0) {
367 job_len
= MAX(job_len
, strlen(u
->job_type
));
371 if (!arg_no_legend
&&
372 (streq(u
->active_state
, "failed") ||
373 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
377 if (!arg_full
&& original_stdout_is_tty
) {
380 id_len
= MIN(max_id_len
, 25u);
381 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
384 basic_len
+= job_len
+ 1;
386 if (basic_len
< (unsigned) columns()) {
387 unsigned extra_len
, incr
;
388 extra_len
= columns() - basic_len
;
390 /* Either UNIT already got 25, or is fully satisfied.
391 * Grant up to 25 to DESC now. */
392 incr
= MIN(extra_len
, 25u);
396 /* split the remaining space between UNIT and DESC,
397 * but do not give UNIT more than it needs. */
399 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
401 desc_len
+= extra_len
- incr
;
407 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
408 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
409 const char *on_loaded
= "", *off_loaded
= "";
410 const char *on_active
= "", *off_active
= "";
411 const char *on_circle
= "", *off_circle
= "";
415 if (!n_shown
&& !arg_no_legend
) {
420 printf("%-*s %-*s %-*s %-*s ",
423 active_len
, "ACTIVE",
427 printf("%-*s ", job_len
, "JOB");
429 if (!arg_full
&& arg_no_pager
)
430 printf("%.*s\n", desc_len
, "DESCRIPTION");
432 printf("%s\n", "DESCRIPTION");
437 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
438 on_loaded
= ansi_highlight_red();
439 on_circle
= ansi_highlight_yellow();
440 off_loaded
= off_circle
= ansi_normal();
442 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
443 on_circle
= on_active
= ansi_highlight_red();
444 off_circle
= off_active
= ansi_normal();
449 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
458 e
= ellipsize(id
, id_len
, 33);
466 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
468 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
469 on_active
, id_len
, id
, off_active
,
470 on_loaded
, load_len
, u
->load_state
, off_loaded
,
471 on_active
, active_len
, u
->active_state
,
472 sub_len
, u
->sub_state
, off_active
,
473 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
476 printf("%.*s\n", desc_len
, u
->description
);
478 printf("%s\n", u
->description
);
481 if (!arg_no_legend
) {
482 const char *on
, *off
;
486 "LOAD = Reflects whether the unit definition was properly loaded.\n"
487 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
488 "SUB = The low-level unit activation state, values depend on unit type.");
489 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
490 on
= ansi_highlight();
493 on
= ansi_highlight_red();
498 printf("%s%u loaded units listed.%s\n"
499 "To show all installed unit files use 'systemctl list-unit-files'.\n",
502 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
503 "To show all installed unit files use 'systemctl list-unit-files'.\n",
510 static int get_unit_list(
514 UnitInfo
**unit_infos
,
516 sd_bus_message
**_reply
) {
518 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
519 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
520 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
529 r
= sd_bus_message_new_method_call(
532 "org.freedesktop.systemd1",
533 "/org/freedesktop/systemd1",
534 "org.freedesktop.systemd1.Manager",
535 "ListUnitsFiltered");
538 return bus_log_create_error(r
);
540 r
= sd_bus_message_append_strv(m
, arg_states
);
542 return bus_log_create_error(r
);
544 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
546 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
548 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
550 return bus_log_parse_error(r
);
552 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
555 if (!output_show_unit(&u
, patterns
))
558 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
561 (*unit_infos
)[c
++] = u
;
564 return bus_log_parse_error(r
);
566 r
= sd_bus_message_exit_container(reply
);
568 return bus_log_parse_error(r
);
576 static void message_set_freep(Set
**set
) {
579 while ((m
= set_steal_first(*set
)))
580 sd_bus_message_unref(m
);
585 static int get_unit_list_recursive(
588 UnitInfo
**_unit_infos
,
592 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
593 _cleanup_(message_set_freep
) Set
*replies
;
594 sd_bus_message
*reply
;
602 replies
= set_new(NULL
);
606 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
610 r
= set_put(replies
, reply
);
612 sd_bus_message_unref(reply
);
617 _cleanup_strv_free_
char **machines
= NULL
;
620 r
= sd_get_machine_names(&machines
);
622 return log_error_errno(r
, "Failed to get machine names: %m");
624 STRV_FOREACH(i
, machines
) {
625 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
628 r
= sd_bus_open_system_machine(&container
, *i
);
630 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
634 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
640 r
= set_put(replies
, reply
);
642 sd_bus_message_unref(reply
);
647 *_machines
= machines
;
652 *_unit_infos
= unit_infos
;
661 static int list_units(int argc
, char *argv
[], void *userdata
) {
662 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
663 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
664 _cleanup_strv_free_
char **machines
= NULL
;
668 pager_open_if_enabled();
670 r
= acquire_bus(BUS_MANAGER
, &bus
);
674 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
678 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
679 return output_units_list(unit_infos
, r
);
682 static int get_triggered_units(
687 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
694 r
= sd_bus_get_property_strv(
696 "org.freedesktop.systemd1",
698 "org.freedesktop.systemd1.Unit",
703 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
708 static int get_listening(
710 const char* unit_path
,
713 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
714 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
715 const char *type
, *path
;
718 r
= sd_bus_get_property(
720 "org.freedesktop.systemd1",
722 "org.freedesktop.systemd1.Socket",
728 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
730 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
732 return bus_log_parse_error(r
);
734 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
736 r
= strv_extend(listening
, type
);
740 r
= strv_extend(listening
, path
);
747 return bus_log_parse_error(r
);
749 r
= sd_bus_message_exit_container(reply
);
751 return bus_log_parse_error(r
);
763 /* Note: triggered is a list here, although it almost certainly
764 * will always be one unit. Nevertheless, dbus API allows for multiple
765 * values, so let's follow that. */
768 /* The strv above is shared. free is set only in the first one. */
772 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
778 if (!a
->machine
&& b
->machine
)
780 if (a
->machine
&& !b
->machine
)
782 if (a
->machine
&& b
->machine
) {
783 o
= strcasecmp(a
->machine
, b
->machine
);
788 o
= strcmp(a
->path
, b
->path
);
790 o
= strcmp(a
->type
, b
->type
);
795 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
796 struct socket_info
*s
;
797 unsigned pathlen
= strlen("LISTEN"),
798 typelen
= strlen("TYPE") * arg_show_types
,
799 socklen
= strlen("UNIT"),
800 servlen
= strlen("ACTIVATES");
801 const char *on
, *off
;
803 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
807 socklen
= MAX(socklen
, strlen(s
->id
));
809 typelen
= MAX(typelen
, strlen(s
->type
));
810 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
812 STRV_FOREACH(a
, s
->triggered
)
813 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
814 servlen
= MAX(servlen
, tmp
);
819 printf("%-*s %-*.*s%-*s %s\n",
821 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
825 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
826 _cleanup_free_
char *j
= NULL
;
831 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
839 printf("%-*s %-*s %-*s",
840 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
843 pathlen
, path
, socklen
, s
->id
);
844 STRV_FOREACH(a
, s
->triggered
)
846 a
== s
->triggered
? "" : ",", *a
);
850 on
= ansi_highlight();
855 on
= ansi_highlight_red();
859 if (!arg_no_legend
) {
860 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
862 printf("Pass --all to see loaded but inactive sockets, too.\n");
868 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
869 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
870 _cleanup_strv_free_
char **machines
= NULL
;
871 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
872 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
874 struct socket_info
*s
;
880 pager_open_if_enabled();
882 r
= acquire_bus(BUS_MANAGER
, &bus
);
886 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
890 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
891 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
894 if (!endswith(u
->id
, ".socket"))
897 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
901 c
= get_listening(bus
, u
->unit_path
, &listening
);
907 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
912 for (i
= 0; i
< c
; i
++)
913 socket_infos
[cs
+ i
] = (struct socket_info
) {
914 .machine
= u
->machine
,
916 .type
= listening
[i
*2],
917 .path
= listening
[i
*2 + 1],
918 .triggered
= triggered
,
919 .own_triggered
= i
==0,
922 /* from this point on we will cleanup those socket_infos */
925 listening
= triggered
= NULL
; /* avoid cleanup */
928 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
929 (__compar_fn_t
) socket_info_compare
);
931 output_sockets_list(socket_infos
, cs
);
934 assert(cs
== 0 || socket_infos
);
935 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
938 if (s
->own_triggered
)
939 strv_free(s
->triggered
);
945 static int get_next_elapse(
948 dual_timestamp
*next
) {
950 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
958 r
= sd_bus_get_property_trivial(
960 "org.freedesktop.systemd1",
962 "org.freedesktop.systemd1.Timer",
963 "NextElapseUSecMonotonic",
968 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
970 r
= sd_bus_get_property_trivial(
972 "org.freedesktop.systemd1",
974 "org.freedesktop.systemd1.Timer",
975 "NextElapseUSecRealtime",
980 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
986 static int get_last_trigger(
991 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
998 r
= sd_bus_get_property_trivial(
1000 "org.freedesktop.systemd1",
1002 "org.freedesktop.systemd1.Timer",
1008 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1014 const char* machine
;
1017 usec_t last_trigger
;
1021 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1027 if (!a
->machine
&& b
->machine
)
1029 if (a
->machine
&& !b
->machine
)
1031 if (a
->machine
&& b
->machine
) {
1032 o
= strcasecmp(a
->machine
, b
->machine
);
1037 if (a
->next_elapse
< b
->next_elapse
)
1039 if (a
->next_elapse
> b
->next_elapse
)
1042 return strcmp(a
->id
, b
->id
);
1045 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1046 struct timer_info
*t
;
1048 nextlen
= strlen("NEXT"),
1049 leftlen
= strlen("LEFT"),
1050 lastlen
= strlen("LAST"),
1051 passedlen
= strlen("PASSED"),
1052 unitlen
= strlen("UNIT"),
1053 activatelen
= strlen("ACTIVATES");
1055 const char *on
, *off
;
1057 assert(timer_infos
|| n
== 0);
1059 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1063 if (t
->next_elapse
> 0) {
1064 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1066 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1067 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1069 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1070 leftlen
= MAX(leftlen
, strlen(trel
));
1073 if (t
->last_trigger
> 0) {
1074 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1076 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1077 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1079 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1080 passedlen
= MAX(passedlen
, strlen(trel
));
1083 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1085 STRV_FOREACH(a
, t
->triggered
)
1086 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1088 activatelen
= MAX(activatelen
, ul
);
1093 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1097 passedlen
, "PASSED",
1101 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1102 _cleanup_free_
char *j
= NULL
;
1104 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1105 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1108 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1109 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1111 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1112 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1115 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1122 printf("%-*s %-*s %-*s %-*s %-*s",
1123 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1125 STRV_FOREACH(a
, t
->triggered
)
1127 a
== t
->triggered
? "" : ",", *a
);
1131 on
= ansi_highlight();
1132 off
= ansi_normal();
1136 on
= ansi_highlight_red();
1137 off
= ansi_normal();
1140 if (!arg_no_legend
) {
1141 printf("%s%u timers listed.%s\n", on
, n
, off
);
1143 printf("Pass --all to see loaded but inactive timers, too.\n");
1149 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1155 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1158 if (next
->monotonic
> nw
->monotonic
)
1159 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1161 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1163 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1164 next_elapse
= MIN(converted
, next
->realtime
);
1166 next_elapse
= converted
;
1169 next_elapse
= next
->realtime
;
1174 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1175 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1176 _cleanup_strv_free_
char **machines
= NULL
;
1177 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1178 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1179 struct timer_info
*t
;
1187 pager_open_if_enabled();
1189 r
= acquire_bus(BUS_MANAGER
, &bus
);
1193 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1197 dual_timestamp_get(&nw
);
1199 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1200 _cleanup_strv_free_
char **triggered
= NULL
;
1201 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1204 if (!endswith(u
->id
, ".timer"))
1207 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1211 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1215 get_last_trigger(bus
, u
->unit_path
, &last
);
1217 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1222 m
= calc_next_elapse(&nw
, &next
);
1224 timer_infos
[c
++] = (struct timer_info
) {
1225 .machine
= u
->machine
,
1228 .last_trigger
= last
,
1229 .triggered
= triggered
,
1232 triggered
= NULL
; /* avoid cleanup */
1235 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1236 (__compar_fn_t
) timer_info_compare
);
1238 output_timers_list(timer_infos
, c
);
1241 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1242 strv_free(t
->triggered
);
1247 static int compare_unit_file_list(const void *a
, const void *b
) {
1248 const char *d1
, *d2
;
1249 const UnitFileList
*u
= a
, *v
= b
;
1251 d1
= strrchr(u
->path
, '.');
1252 d2
= strrchr(v
->path
, '.');
1257 r
= strcasecmp(d1
, d2
);
1262 return strcasecmp(basename(u
->path
), basename(v
->path
));
1265 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1266 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1269 if (!strv_isempty(arg_types
)) {
1272 dot
= strrchr(u
->path
, '.');
1276 if (!strv_find(arg_types
, dot
+1))
1280 if (!strv_isempty(arg_states
) &&
1281 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1287 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1288 unsigned max_id_len
, id_cols
, state_cols
;
1289 const UnitFileList
*u
;
1291 max_id_len
= strlen("UNIT FILE");
1292 state_cols
= strlen("STATE");
1294 for (u
= units
; u
< units
+ c
; u
++) {
1295 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1296 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1300 unsigned basic_cols
;
1302 id_cols
= MIN(max_id_len
, 25u);
1303 basic_cols
= 1 + id_cols
+ state_cols
;
1304 if (basic_cols
< (unsigned) columns())
1305 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1307 id_cols
= max_id_len
;
1310 printf("%-*s %-*s\n",
1311 id_cols
, "UNIT FILE",
1312 state_cols
, "STATE");
1314 for (u
= units
; u
< units
+ c
; u
++) {
1315 _cleanup_free_
char *e
= NULL
;
1316 const char *on
, *off
;
1319 if (IN_SET(u
->state
,
1321 UNIT_FILE_MASKED_RUNTIME
,
1323 UNIT_FILE_INVALID
)) {
1324 on
= ansi_highlight_red();
1325 off
= ansi_normal();
1326 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1327 on
= ansi_highlight_green();
1328 off
= ansi_normal();
1332 id
= basename(u
->path
);
1334 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1336 printf("%-*s %s%-*s%s\n",
1337 id_cols
, e
? e
: id
,
1338 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1342 printf("\n%u unit files listed.\n", c
);
1345 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1346 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1347 _cleanup_free_ UnitFileList
*units
= NULL
;
1355 pager_open_if_enabled();
1357 if (install_client_side()) {
1363 h
= hashmap_new(&string_hash_ops
);
1367 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1369 unit_file_list_free(h
);
1370 return log_error_errno(r
, "Failed to get unit file list: %m");
1373 n_units
= hashmap_size(h
);
1375 units
= new(UnitFileList
, n_units
);
1376 if (!units
&& n_units
> 0) {
1377 unit_file_list_free(h
);
1381 HASHMAP_FOREACH(u
, h
, i
) {
1382 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1389 assert(c
<= n_units
);
1392 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1395 r
= acquire_bus(BUS_MANAGER
, &bus
);
1399 r
= sd_bus_call_method(
1401 "org.freedesktop.systemd1",
1402 "/org/freedesktop/systemd1",
1403 "org.freedesktop.systemd1.Manager",
1409 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1411 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1413 return bus_log_parse_error(r
);
1415 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1417 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1420 units
[c
] = (struct UnitFileList
) {
1422 unit_file_state_from_string(state
)
1425 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1430 return bus_log_parse_error(r
);
1432 r
= sd_bus_message_exit_container(reply
);
1434 return bus_log_parse_error(r
);
1437 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1438 output_unit_file_list(units
, c
);
1440 if (install_client_side()) {
1441 for (unit
= units
; unit
< units
+ c
; unit
++)
1448 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1449 _cleanup_free_
char *n
= NULL
;
1450 size_t max_len
= MAX(columns(),20u);
1456 for (i
= level
- 1; i
>= 0; i
--) {
1458 if (len
> max_len
- 3 && !arg_full
) {
1459 printf("%s...\n",max_len
% 2 ? "" : " ");
1462 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1466 if (len
> max_len
- 3 && !arg_full
) {
1467 printf("%s...\n",max_len
% 2 ? "" : " ");
1471 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1475 printf("%s\n", name
);
1479 n
= ellipsize(name
, max_len
-len
, 100);
1487 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1489 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1490 [DEPENDENCY_FORWARD
] = "Requires\0"
1491 "RequiresOverridable\0"
1493 "RequisiteOverridable\0"
1497 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1498 "RequiredByOverridable\0"
1500 "RequisiteOfOverridable\0"
1504 [DEPENDENCY_AFTER
] = "After\0",
1505 [DEPENDENCY_BEFORE
] = "Before\0",
1508 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1509 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1510 _cleanup_strv_free_
char **ret
= NULL
;
1511 _cleanup_free_
char *path
= NULL
;
1517 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1519 path
= unit_dbus_path_from_name(name
);
1523 r
= sd_bus_call_method(
1525 "org.freedesktop.systemd1",
1527 "org.freedesktop.DBus.Properties",
1531 "s", "org.freedesktop.systemd1.Unit");
1533 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1535 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1537 return bus_log_parse_error(r
);
1539 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1542 r
= sd_bus_message_read(reply
, "s", &prop
);
1544 return bus_log_parse_error(r
);
1546 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1547 r
= sd_bus_message_skip(reply
, "v");
1549 return bus_log_parse_error(r
);
1552 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1554 return bus_log_parse_error(r
);
1556 r
= bus_message_read_strv_extend(reply
, &ret
);
1558 return bus_log_parse_error(r
);
1560 r
= sd_bus_message_exit_container(reply
);
1562 return bus_log_parse_error(r
);
1565 r
= sd_bus_message_exit_container(reply
);
1567 return bus_log_parse_error(r
);
1571 return bus_log_parse_error(r
);
1573 r
= sd_bus_message_exit_container(reply
);
1575 return bus_log_parse_error(r
);
1583 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1584 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1586 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1588 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1591 return strcasecmp(*a
, *b
);
1594 static int list_dependencies_one(
1599 unsigned int branches
) {
1601 _cleanup_strv_free_
char **deps
= NULL
;
1609 r
= strv_extend(units
, name
);
1613 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1617 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1619 STRV_FOREACH(c
, deps
) {
1620 if (strv_contains(*units
, *c
)) {
1622 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1635 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1636 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1637 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1640 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1644 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1645 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1652 strv_remove(*units
, name
);
1657 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1658 _cleanup_strv_free_
char **units
= NULL
;
1659 _cleanup_free_
char *unit
= NULL
;
1665 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1667 return log_error_errno(r
, "Failed to mangle unit name: %m");
1671 u
= SPECIAL_DEFAULT_TARGET
;
1673 pager_open_if_enabled();
1675 r
= acquire_bus(BUS_MANAGER
, &bus
);
1681 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1684 struct machine_info
{
1688 char *control_group
;
1689 uint32_t n_failed_units
;
1694 static const struct bus_properties_map machine_info_property_map
[] = {
1695 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1696 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1697 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1698 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1699 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1703 static void machine_info_clear(struct machine_info
*info
) {
1707 free(info
->control_group
);
1712 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1718 for (i
= 0; i
< n
; i
++)
1719 machine_info_clear(&machine_infos
[i
]);
1721 free(machine_infos
);
1724 static int compare_machine_info(const void *a
, const void *b
) {
1725 const struct machine_info
*u
= a
, *v
= b
;
1727 if (u
->is_host
!= v
->is_host
)
1728 return u
->is_host
> v
->is_host
? -1 : 1;
1730 return strcasecmp(u
->name
, v
->name
);
1733 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1734 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1740 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1747 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1754 static bool output_show_machine(const char *name
, char **patterns
) {
1755 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1758 static int get_machine_list(
1760 struct machine_info
**_machine_infos
,
1763 struct machine_info
*machine_infos
= NULL
;
1764 _cleanup_strv_free_
char **m
= NULL
;
1765 _cleanup_free_
char *hn
= NULL
;
1770 hn
= gethostname_malloc();
1774 if (output_show_machine(hn
, patterns
)) {
1775 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1778 machine_infos
[c
].is_host
= true;
1779 machine_infos
[c
].name
= hn
;
1782 get_machine_properties(bus
, &machine_infos
[c
]);
1786 r
= sd_get_machine_names(&m
);
1788 return log_error_errno(r
, "Failed to get machine list: %m");
1790 STRV_FOREACH(i
, m
) {
1791 _cleanup_free_
char *class = NULL
;
1793 if (!output_show_machine(*i
, patterns
))
1796 sd_machine_get_class(*i
, &class);
1797 if (!streq_ptr(class, "container"))
1800 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1801 free_machines_list(machine_infos
, c
);
1805 machine_infos
[c
].is_host
= false;
1806 machine_infos
[c
].name
= strdup(*i
);
1807 if (!machine_infos
[c
].name
) {
1808 free_machines_list(machine_infos
, c
);
1812 get_machine_properties(NULL
, &machine_infos
[c
]);
1816 *_machine_infos
= machine_infos
;
1820 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1821 struct machine_info
*m
;
1824 namelen
= sizeof("NAME") - 1,
1825 statelen
= sizeof("STATE") - 1,
1826 failedlen
= sizeof("FAILED") - 1,
1827 jobslen
= sizeof("JOBS") - 1;
1829 assert(machine_infos
|| n
== 0);
1831 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1832 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1833 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1834 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1835 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1837 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1841 if (!arg_no_legend
) {
1845 printf("%-*s %-*s %-*s %-*s\n",
1848 failedlen
, "FAILED",
1852 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1853 const char *on_state
= "", *off_state
= "";
1854 const char *on_failed
= "", *off_failed
= "";
1855 bool circle
= false;
1857 if (streq_ptr(m
->state
, "degraded")) {
1858 on_state
= ansi_highlight_red();
1859 off_state
= ansi_normal();
1861 } else if (!streq_ptr(m
->state
, "running")) {
1862 on_state
= ansi_highlight_yellow();
1863 off_state
= ansi_normal();
1867 if (m
->n_failed_units
> 0) {
1868 on_failed
= ansi_highlight_red();
1869 off_failed
= ansi_normal();
1871 on_failed
= off_failed
= "";
1874 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1877 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1878 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1879 on_state
, statelen
, strna(m
->state
), off_state
,
1880 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1881 jobslen
, m
->n_jobs
);
1883 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1884 namelen
, strna(m
->name
),
1885 on_state
, statelen
, strna(m
->state
), off_state
,
1886 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1887 jobslen
, m
->n_jobs
);
1891 printf("\n%u machines listed.\n", n
);
1894 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1895 struct machine_info
*machine_infos
= NULL
;
1899 if (geteuid() != 0) {
1900 log_error("Must be root.");
1904 pager_open_if_enabled();
1906 r
= acquire_bus(BUS_MANAGER
, &bus
);
1910 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1914 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1915 output_machines_list(machine_infos
, r
);
1916 free_machines_list(machine_infos
, r
);
1921 static int get_default(int argc
, char *argv
[], void *userdata
) {
1922 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1923 _cleanup_free_
char *_path
= NULL
;
1927 if (install_client_side()) {
1928 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1930 return log_error_errno(r
, "Failed to get default target: %m");
1934 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1937 r
= acquire_bus(BUS_MANAGER
, &bus
);
1941 r
= sd_bus_call_method(
1943 "org.freedesktop.systemd1",
1944 "/org/freedesktop/systemd1",
1945 "org.freedesktop.systemd1.Manager",
1951 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1953 r
= sd_bus_message_read(reply
, "s", &path
);
1955 return bus_log_parse_error(r
);
1959 printf("%s\n", path
);
1964 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1967 assert(changes
|| n_changes
== 0);
1969 for (i
= 0; i
< n_changes
; i
++) {
1970 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1971 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1973 log_info("Removed symlink %s.", changes
[i
].path
);
1977 static int set_default(int argc
, char *argv
[], void *userdata
) {
1978 _cleanup_free_
char *unit
= NULL
;
1984 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1986 return log_error_errno(r
, "Failed to mangle unit name: %m");
1988 if (install_client_side()) {
1989 UnitFileChange
*changes
= NULL
;
1990 unsigned n_changes
= 0;
1992 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1994 return log_error_errno(r
, "Failed to set default target: %m");
1997 dump_unit_file_changes(changes
, n_changes
);
1999 unit_file_changes_free(changes
, n_changes
);
2002 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2003 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2006 polkit_agent_open_if_enabled();
2008 r
= acquire_bus(BUS_MANAGER
, &bus
);
2012 r
= sd_bus_call_method(
2014 "org.freedesktop.systemd1",
2015 "/org/freedesktop/systemd1",
2016 "org.freedesktop.systemd1.Manager",
2022 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2024 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2028 /* Try to reload if enabled */
2030 r
= daemon_reload(argc
, argv
, userdata
);
2040 const char *name
, *type
, *state
;
2043 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2044 unsigned id_len
, unit_len
, type_len
, state_len
;
2045 const struct job_info
*j
;
2046 const char *on
, *off
;
2047 bool shorten
= false;
2049 assert(n
== 0 || jobs
);
2052 if (!arg_no_legend
) {
2053 on
= ansi_highlight_green();
2054 off
= ansi_normal();
2056 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2061 pager_open_if_enabled();
2063 id_len
= strlen("JOB");
2064 unit_len
= strlen("UNIT");
2065 type_len
= strlen("TYPE");
2066 state_len
= strlen("STATE");
2068 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2069 uint32_t id
= j
->id
;
2070 assert(j
->name
&& j
->type
&& j
->state
);
2072 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2073 unit_len
= MAX(unit_len
, strlen(j
->name
));
2074 type_len
= MAX(type_len
, strlen(j
->type
));
2075 state_len
= MAX(state_len
, strlen(j
->state
));
2078 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2079 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2084 printf("%*s %-*s %-*s %-*s\n",
2088 state_len
, "STATE");
2090 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2091 _cleanup_free_
char *e
= NULL
;
2093 if (streq(j
->state
, "running")) {
2094 on
= ansi_highlight();
2095 off
= ansi_normal();
2099 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2100 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2102 on
, unit_len
, e
? e
: j
->name
, off
,
2104 on
, state_len
, j
->state
, off
);
2107 if (!arg_no_legend
) {
2108 on
= ansi_highlight();
2109 off
= ansi_normal();
2111 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2115 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2116 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2119 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2120 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2121 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2122 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2123 _cleanup_free_
struct job_info
*jobs
= NULL
;
2129 bool skipped
= false;
2131 pager_open_if_enabled();
2133 r
= acquire_bus(BUS_MANAGER
, &bus
);
2137 r
= sd_bus_call_method(
2139 "org.freedesktop.systemd1",
2140 "/org/freedesktop/systemd1",
2141 "org.freedesktop.systemd1.Manager",
2147 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2149 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2151 return bus_log_parse_error(r
);
2153 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2154 struct job_info job
= { id
, name
, type
, state
};
2156 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2161 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2167 return bus_log_parse_error(r
);
2169 r
= sd_bus_message_exit_container(reply
);
2171 return bus_log_parse_error(r
);
2173 output_jobs_list(jobs
, c
, skipped
);
2177 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2183 return daemon_reload(argc
, argv
, userdata
);
2185 polkit_agent_open_if_enabled();
2187 r
= acquire_bus(BUS_MANAGER
, &bus
);
2191 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2192 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2196 q
= safe_atou32(*name
, &id
);
2198 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2200 q
= sd_bus_call_method(
2202 "org.freedesktop.systemd1",
2203 "/org/freedesktop/systemd1",
2204 "org.freedesktop.systemd1.Manager",
2210 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2219 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2220 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2224 /* We ignore all errors here, since this is used to show a
2227 /* We don't use unit_dbus_path_from_name() directly since we
2228 * don't want to load the unit if it isn't loaded. */
2230 r
= sd_bus_call_method(
2232 "org.freedesktop.systemd1",
2233 "/org/freedesktop/systemd1",
2234 "org.freedesktop.systemd1.Manager",
2242 r
= sd_bus_message_read(reply
, "o", &path
);
2246 r
= sd_bus_get_property_trivial(
2248 "org.freedesktop.systemd1",
2250 "org.freedesktop.systemd1.Unit",
2260 static void warn_unit_file_changed(const char *name
) {
2261 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2262 ansi_highlight_red(),
2265 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2268 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2275 STRV_FOREACH(p
, lp
->unit_path
) {
2276 _cleanup_free_
char *path
;
2278 path
= path_join(arg_root
, *p
, unit_name
);
2282 if (access(path
, F_OK
) == 0) {
2292 static int unit_find_paths(
2294 const char *unit_name
,
2296 char **fragment_path
,
2297 char ***dropin_paths
) {
2299 _cleanup_free_
char *path
= NULL
;
2300 _cleanup_strv_free_
char **dropins
= NULL
;
2304 * Finds where the unit is defined on disk. Returns 0 if the unit
2305 * is not found. Returns 1 if it is found, and sets
2306 * - the path to the unit in *path, if it exists on disk,
2307 * - and a strv of existing drop-ins in *dropins,
2308 * if the arg is not NULL and any dropins were found.
2312 assert(fragment_path
);
2315 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2316 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2317 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2318 _cleanup_free_
char *unit
= NULL
;
2319 char *unit_load_error_name
, *unit_load_error_message
;
2321 unit
= unit_dbus_path_from_name(unit_name
);
2325 if (need_daemon_reload(bus
, unit_name
) > 0)
2326 warn_unit_file_changed(unit_name
);
2328 r
= sd_bus_get_property(
2330 "org.freedesktop.systemd1",
2332 "org.freedesktop.systemd1.Unit",
2338 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2340 r
= sd_bus_message_read(
2343 &unit_load_error_name
,
2344 &unit_load_error_message
);
2346 return bus_log_parse_error(r
);
2348 if (!isempty(unit_load_error_name
)) {
2349 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2353 r
= sd_bus_get_property_string(
2355 "org.freedesktop.systemd1",
2357 "org.freedesktop.systemd1.Unit",
2362 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2365 r
= sd_bus_get_property_strv(
2367 "org.freedesktop.systemd1",
2369 "org.freedesktop.systemd1.Unit",
2374 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2377 _cleanup_set_free_ Set
*names
;
2379 names
= set_new(NULL
);
2383 r
= set_put(names
, unit_name
);
2385 return log_error_errno(r
, "Failed to add unit name: %m");
2387 r
= unit_file_find_path(lp
, unit_name
, &path
);
2392 _cleanup_free_
char *template = NULL
;
2394 r
= unit_name_template(unit_name
, &template);
2395 if (r
< 0 && r
!= -EINVAL
)
2396 return log_error_errno(r
, "Failed to determine template name: %m");
2398 r
= unit_file_find_path(lp
, template, &path
);
2405 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2413 if (!isempty(path
)) {
2414 *fragment_path
= path
;
2419 if (dropin_paths
&& !strv_isempty(dropins
)) {
2420 *dropin_paths
= dropins
;
2426 log_error("No files found for %s.", unit_name
);
2431 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2432 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2433 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2439 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2441 return log_error_errno(r
, "Failed to mangle unit name: %m");
2443 /* We don't use unit_dbus_path_from_name() directly since we
2444 * don't want to load the unit if it isn't loaded. */
2446 r
= sd_bus_call_method(
2448 "org.freedesktop.systemd1",
2449 "/org/freedesktop/systemd1",
2450 "org.freedesktop.systemd1.Manager",
2461 r
= sd_bus_message_read(reply
, "o", &path
);
2463 return bus_log_parse_error(r
);
2465 r
= sd_bus_get_property_string(
2467 "org.freedesktop.systemd1",
2469 "org.freedesktop.systemd1.Unit",
2482 return nulstr_contains(good_states
, state
);
2485 static int check_triggering_units(
2489 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2490 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2491 _cleanup_strv_free_
char **triggered_by
= NULL
;
2492 bool print_warning_label
= true;
2496 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2498 return log_error_errno(r
, "Failed to mangle unit name: %m");
2500 path
= unit_dbus_path_from_name(n
);
2504 r
= sd_bus_get_property_string(
2506 "org.freedesktop.systemd1",
2508 "org.freedesktop.systemd1.Unit",
2513 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2515 if (streq(state
, "masked"))
2518 r
= sd_bus_get_property_strv(
2520 "org.freedesktop.systemd1",
2522 "org.freedesktop.systemd1.Unit",
2527 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2529 STRV_FOREACH(i
, triggered_by
) {
2530 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2532 return log_error_errno(r
, "Failed to check unit: %m");
2537 if (print_warning_label
) {
2538 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2539 print_warning_label
= false;
2542 log_warning(" %s", *i
);
2548 static const struct {
2551 } unit_actions
[] = {
2552 { "start", "StartUnit" },
2553 { "stop", "StopUnit" },
2554 { "condstop", "StopUnit" },
2555 { "reload", "ReloadUnit" },
2556 { "restart", "RestartUnit" },
2557 { "try-restart", "TryRestartUnit" },
2558 { "condrestart", "TryRestartUnit" },
2559 { "reload-or-restart", "ReloadOrRestartUnit" },
2560 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2561 { "condreload", "ReloadOrTryRestartUnit" },
2562 { "force-reload", "ReloadOrTryRestartUnit" }
2565 static const char *verb_to_method(const char *verb
) {
2568 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2569 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2570 return unit_actions
[i
].method
;
2575 static const char *method_to_verb(const char *method
) {
2578 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2579 if (streq_ptr(unit_actions
[i
].method
, method
))
2580 return unit_actions
[i
].verb
;
2585 static int start_unit_one(
2590 sd_bus_error
*error
,
2591 BusWaitForJobs
*w
) {
2593 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2602 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2604 r
= sd_bus_call_method(
2606 "org.freedesktop.systemd1",
2607 "/org/freedesktop/systemd1",
2608 "org.freedesktop.systemd1.Manager",
2616 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2617 /* There's always a fallback possible for
2618 * legacy actions. */
2619 return -EADDRNOTAVAIL
;
2621 verb
= method_to_verb(method
);
2623 return log_error_errno(r
, "Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2626 r
= sd_bus_message_read(reply
, "o", &path
);
2628 return bus_log_parse_error(r
);
2630 if (need_daemon_reload(bus
, name
) > 0)
2631 warn_unit_file_changed(name
);
2634 log_debug("Adding %s to the set", path
);
2635 r
= bus_wait_for_jobs_add(w
, path
);
2643 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2644 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2651 STRV_FOREACH(name
, names
) {
2655 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2657 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2659 return log_error_errno(r
, "Failed to mangle name: %m");
2661 if (string_is_glob(t
))
2662 r
= strv_consume(&globs
, t
);
2664 r
= strv_consume(&mangled
, t
);
2669 /* Query the manager only if any of the names are a glob, since
2670 * this is fairly expensive */
2671 if (!strv_isempty(globs
)) {
2672 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2673 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2675 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2679 for (i
= 0; i
< r
; i
++)
2680 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2685 mangled
= NULL
; /* do not free */
2690 static const struct {
2694 } action_table
[_ACTION_MAX
] = {
2695 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2696 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2697 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2698 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2699 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2700 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2701 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2702 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2703 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2704 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2705 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2706 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2707 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2708 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2709 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2712 static enum action
verb_to_action(const char *verb
) {
2715 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2716 if (streq_ptr(action_table
[i
].verb
, verb
))
2719 return _ACTION_INVALID
;
2722 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2723 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2724 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2725 _cleanup_strv_free_
char **names
= NULL
;
2730 ask_password_agent_open_if_enabled();
2731 polkit_agent_open_if_enabled();
2733 r
= acquire_bus(BUS_MANAGER
, &bus
);
2737 if (arg_action
== ACTION_SYSTEMCTL
) {
2740 method
= verb_to_method(argv
[0]);
2741 action
= verb_to_action(argv
[0]);
2743 if (streq(argv
[0], "isolate")) {
2747 mode
= action_table
[action
].mode
?: arg_job_mode
;
2749 one_name
= action_table
[action
].target
;
2751 assert(arg_action
< ELEMENTSOF(action_table
));
2752 assert(action_table
[arg_action
].target
);
2754 method
= "StartUnit";
2756 mode
= action_table
[arg_action
].mode
;
2757 one_name
= action_table
[arg_action
].target
;
2761 names
= strv_new(one_name
, NULL
);
2763 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2765 return log_error_errno(r
, "Failed to expand names: %m");
2768 if (!arg_no_block
) {
2769 r
= bus_wait_for_jobs_new(bus
, &w
);
2771 return log_error_errno(r
, "Could not watch jobs: %m");
2774 STRV_FOREACH(name
, names
) {
2775 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2778 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2779 if (r
>= 0 && q
< 0)
2780 r
= translate_bus_error_to_exit_status(q
, &error
);
2783 if (!arg_no_block
) {
2786 q
= bus_wait_for_jobs(w
, arg_quiet
);
2790 /* When stopping units, warn if they can still be triggered by
2791 * another active unit (socket, path, timer) */
2792 if (!arg_quiet
&& streq(method
, "StopUnit"))
2793 STRV_FOREACH(name
, names
)
2794 check_triggering_units(bus
, *name
);
2800 static int logind_set_wall_message(void) {
2802 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2804 _cleanup_free_
char *m
= NULL
;
2807 r
= acquire_bus(BUS_FULL
, &bus
);
2811 m
= strv_join(arg_wall
, " ");
2815 r
= sd_bus_call_method(
2817 "org.freedesktop.login1",
2818 "/org/freedesktop/login1",
2819 "org.freedesktop.login1.Manager",
2828 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2834 /* Ask systemd-logind, which might grant access to unprivileged users
2835 * through PolicyKit */
2836 static int logind_reboot(enum action a
) {
2838 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2839 const char *method
, *description
;
2843 polkit_agent_open_if_enabled();
2844 (void) logind_set_wall_message();
2846 r
= acquire_bus(BUS_FULL
, &bus
);
2854 description
= "reboot system";
2857 case ACTION_POWEROFF
:
2858 method
= "PowerOff";
2859 description
= "power off system";
2862 case ACTION_SUSPEND
:
2864 description
= "suspend system";
2867 case ACTION_HIBERNATE
:
2868 method
= "Hibernate";
2869 description
= "hibernate system";
2872 case ACTION_HYBRID_SLEEP
:
2873 method
= "HybridSleep";
2874 description
= "put system into hybrid sleep";
2881 r
= sd_bus_call_method(
2883 "org.freedesktop.login1",
2884 "/org/freedesktop/login1",
2885 "org.freedesktop.login1.Manager",
2889 "b", arg_ask_password
);
2891 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2899 static int logind_check_inhibitors(enum action a
) {
2901 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2902 _cleanup_strv_free_
char **sessions
= NULL
;
2903 const char *what
, *who
, *why
, *mode
;
2910 if (arg_ignore_inhibitors
|| arg_force
> 0)
2922 r
= acquire_bus(BUS_FULL
, &bus
);
2926 r
= sd_bus_call_method(
2928 "org.freedesktop.login1",
2929 "/org/freedesktop/login1",
2930 "org.freedesktop.login1.Manager",
2936 /* If logind is not around, then there are no inhibitors... */
2939 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2941 return bus_log_parse_error(r
);
2943 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2944 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2945 _cleanup_strv_free_
char **sv
= NULL
;
2947 if (!streq(mode
, "block"))
2950 sv
= strv_split(what
, ":");
2954 if ((pid_t
) pid
< 0)
2955 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2957 if (!strv_contains(sv
,
2962 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2965 get_process_comm(pid
, &comm
);
2966 user
= uid_to_name(uid
);
2968 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2969 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2974 return bus_log_parse_error(r
);
2976 r
= sd_bus_message_exit_container(reply
);
2978 return bus_log_parse_error(r
);
2980 /* Check for current sessions */
2981 sd_get_sessions(&sessions
);
2982 STRV_FOREACH(s
, sessions
) {
2983 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2985 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2988 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2991 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2994 sd_session_get_tty(*s
, &tty
);
2995 sd_session_get_seat(*s
, &seat
);
2996 sd_session_get_service(*s
, &service
);
2997 user
= uid_to_name(uid
);
2999 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3006 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3007 action_table
[a
].verb
);
3015 static int logind_prepare_firmware_setup(void) {
3017 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3021 r
= acquire_bus(BUS_FULL
, &bus
);
3025 r
= sd_bus_call_method(
3027 "org.freedesktop.login1",
3028 "/org/freedesktop/login1",
3029 "org.freedesktop.login1.Manager",
3030 "SetRebootToFirmwareSetup",
3035 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3039 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3044 static int prepare_firmware_setup(void) {
3047 if (!arg_firmware_setup
)
3050 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3052 r
= efi_set_reboot_to_firmware(true);
3054 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3059 return logind_prepare_firmware_setup();
3062 static int set_exit_code(uint8_t code
) {
3063 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3067 r
= acquire_bus(BUS_MANAGER
, &bus
);
3071 r
= sd_bus_call_method(
3073 "org.freedesktop.systemd1",
3074 "/org/freedesktop/systemd1",
3075 "org.freedesktop.systemd1.Manager",
3081 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3086 static int start_special(int argc
, char *argv
[], void *userdata
) {
3092 a
= verb_to_action(argv
[0]);
3094 r
= logind_check_inhibitors(a
);
3098 if (arg_force
>= 2 && geteuid() != 0) {
3099 log_error("Must be root.");
3103 r
= prepare_firmware_setup();
3107 if (a
== ACTION_REBOOT
&& argc
> 1) {
3108 r
= update_reboot_param_file(argv
[1]);
3112 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3115 /* If the exit code is not given on the command line,
3116 * don't reset it to zero: just keep it as it might
3117 * have been set previously. */
3119 r
= safe_atou8(argv
[1], &code
);
3121 return log_error_errno(r
, "Invalid exit code.");
3123 r
= set_exit_code(code
);
3128 if (arg_force
>= 2 &&
3135 if (arg_force
>= 1 &&
3142 return daemon_reload(argc
, argv
, userdata
);
3144 /* First try logind, to allow authentication with polkit */
3150 ACTION_HYBRID_SLEEP
)) {
3151 r
= logind_reboot(a
);
3154 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3155 /* requested operation is not supported or already in progress */
3158 /* On all other errors, try low-level operation */
3161 return start_unit(argc
, argv
, userdata
);
3164 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3165 _cleanup_strv_free_
char **names
= NULL
;
3170 r
= acquire_bus(BUS_MANAGER
, &bus
);
3174 r
= expand_names(bus
, args
, NULL
, &names
);
3176 return log_error_errno(r
, "Failed to expand names: %m");
3178 STRV_FOREACH(name
, names
) {
3181 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3191 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3192 /* According to LSB: 3, "program is not running" */
3193 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3196 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3197 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3200 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3201 _cleanup_strv_free_
char **names
= NULL
;
3202 char *kill_who
= NULL
, **name
;
3206 polkit_agent_open_if_enabled();
3208 r
= acquire_bus(BUS_MANAGER
, &bus
);
3213 arg_kill_who
= "all";
3215 /* --fail was specified */
3216 if (streq(arg_job_mode
, "fail"))
3217 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3219 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3221 return log_error_errno(r
, "Failed to expand names: %m");
3223 STRV_FOREACH(name
, names
) {
3224 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3226 q
= sd_bus_call_method(
3228 "org.freedesktop.systemd1",
3229 "/org/freedesktop/systemd1",
3230 "org.freedesktop.systemd1.Manager",
3234 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3236 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3245 typedef struct ExecStatusInfo
{
3253 usec_t start_timestamp
;
3254 usec_t exit_timestamp
;
3259 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3262 static void exec_status_info_free(ExecStatusInfo
*i
) {
3271 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3272 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3275 int32_t code
, status
;
3281 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3283 return bus_log_parse_error(r
);
3287 r
= sd_bus_message_read(m
, "s", &path
);
3289 return bus_log_parse_error(r
);
3291 i
->path
= strdup(path
);
3295 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3297 return bus_log_parse_error(r
);
3299 r
= sd_bus_message_read(m
,
3302 &start_timestamp
, &start_timestamp_monotonic
,
3303 &exit_timestamp
, &exit_timestamp_monotonic
,
3307 return bus_log_parse_error(r
);
3310 i
->start_timestamp
= (usec_t
) start_timestamp
;
3311 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3312 i
->pid
= (pid_t
) pid
;
3316 r
= sd_bus_message_exit_container(m
);
3318 return bus_log_parse_error(r
);
3323 typedef struct UnitStatusInfo
{
3325 const char *load_state
;
3326 const char *active_state
;
3327 const char *sub_state
;
3328 const char *unit_file_state
;
3329 const char *unit_file_preset
;
3331 const char *description
;
3332 const char *following
;
3334 char **documentation
;
3336 const char *fragment_path
;
3337 const char *source_path
;
3338 const char *control_group
;
3340 char **dropin_paths
;
3342 const char *load_error
;
3345 usec_t inactive_exit_timestamp
;
3346 usec_t inactive_exit_timestamp_monotonic
;
3347 usec_t active_enter_timestamp
;
3348 usec_t active_exit_timestamp
;
3349 usec_t inactive_enter_timestamp
;
3351 bool need_daemon_reload
;
3356 const char *status_text
;
3357 const char *pid_file
;
3361 usec_t start_timestamp
;
3362 usec_t exit_timestamp
;
3364 int exit_code
, exit_status
;
3366 usec_t condition_timestamp
;
3367 bool condition_result
;
3368 bool failed_condition_trigger
;
3369 bool failed_condition_negate
;
3370 const char *failed_condition
;
3371 const char *failed_condition_parameter
;
3373 usec_t assert_timestamp
;
3375 bool failed_assert_trigger
;
3376 bool failed_assert_negate
;
3377 const char *failed_assert
;
3378 const char *failed_assert_parameter
;
3381 unsigned n_accepted
;
3382 unsigned n_connections
;
3385 /* Pairs of type, path */
3389 const char *sysfs_path
;
3391 /* Mount, Automount */
3398 uint64_t memory_current
;
3399 uint64_t memory_limit
;
3400 uint64_t cpu_usage_nsec
;
3401 uint64_t tasks_current
;
3404 LIST_HEAD(ExecStatusInfo
, exec
);
3407 static void print_status_info(
3412 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3414 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3415 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3421 /* This shows pretty information about a unit. See
3422 * print_property() for a low-level property printer */
3424 if (streq_ptr(i
->active_state
, "failed")) {
3425 active_on
= ansi_highlight_red();
3426 active_off
= ansi_normal();
3427 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3428 active_on
= ansi_highlight_green();
3429 active_off
= ansi_normal();
3431 active_on
= active_off
= "";
3433 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3435 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3436 printf(" - %s", i
->description
);
3441 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3443 if (streq_ptr(i
->load_state
, "error")) {
3444 on
= ansi_highlight_red();
3445 off
= ansi_normal();
3449 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3452 printf(" Loaded: %s%s%s (Reason: %s)\n",
3453 on
, strna(i
->load_state
), off
, i
->load_error
);
3454 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3455 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3456 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3457 else if (path
&& !isempty(i
->unit_file_state
))
3458 printf(" Loaded: %s%s%s (%s; %s)\n",
3459 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3461 printf(" Loaded: %s%s%s (%s)\n",
3462 on
, strna(i
->load_state
), off
, path
);
3464 printf(" Loaded: %s%s%s\n",
3465 on
, strna(i
->load_state
), off
);
3467 if (!strv_isempty(i
->dropin_paths
)) {
3468 _cleanup_free_
char *dir
= NULL
;
3472 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3473 if (! dir
|| last
) {
3474 printf(dir
? " " : " Drop-In: ");
3478 if (path_get_parent(*dropin
, &dir
) < 0) {
3483 printf("%s\n %s", dir
,
3484 draw_special_char(DRAW_TREE_RIGHT
));
3487 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3489 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3493 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3495 printf(" Active: %s%s (%s)%s",
3496 active_on
, strna(i
->active_state
), ss
, active_off
);
3498 printf(" Active: %s%s%s",
3499 active_on
, strna(i
->active_state
), active_off
);
3501 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3502 printf(" (Result: %s)", i
->result
);
3504 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3505 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3506 (streq_ptr(i
->active_state
, "inactive") ||
3507 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3508 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3509 i
->active_exit_timestamp
;
3511 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3512 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3515 printf(" since %s; %s\n", s2
, s1
);
3517 printf(" since %s\n", s2
);
3521 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3522 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3523 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3525 printf("Condition: start %scondition failed%s at %s%s%s\n",
3526 ansi_highlight_yellow(), ansi_normal(),
3527 s2
, s1
? "; " : "", strempty(s1
));
3528 if (i
->failed_condition_trigger
)
3529 printf(" none of the trigger conditions were met\n");
3530 else if (i
->failed_condition
)
3531 printf(" %s=%s%s was not met\n",
3532 i
->failed_condition
,
3533 i
->failed_condition_negate
? "!" : "",
3534 i
->failed_condition_parameter
);
3537 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3538 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3539 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3541 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3542 ansi_highlight_red(), ansi_normal(),
3543 s2
, s1
? "; " : "", strempty(s1
));
3544 if (i
->failed_assert_trigger
)
3545 printf(" none of the trigger assertions were met\n");
3546 else if (i
->failed_assert
)
3547 printf(" %s=%s%s was not met\n",
3549 i
->failed_assert_negate
? "!" : "",
3550 i
->failed_assert_parameter
);
3554 printf(" Device: %s\n", i
->sysfs_path
);
3556 printf(" Where: %s\n", i
->where
);
3558 printf(" What: %s\n", i
->what
);
3560 STRV_FOREACH(t
, i
->documentation
)
3561 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3563 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3564 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3567 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3569 LIST_FOREACH(exec
, p
, i
->exec
) {
3570 _cleanup_free_
char *argv
= NULL
;
3573 /* Only show exited processes here */
3577 argv
= strv_join(p
->argv
, " ");
3578 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3580 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3582 on
= ansi_highlight_red();
3583 off
= ansi_normal();
3587 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3589 if (p
->code
== CLD_EXITED
) {
3592 printf("status=%i", p
->status
);
3594 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3599 printf("signal=%s", signal_to_string(p
->status
));
3601 printf(")%s\n", off
);
3603 if (i
->main_pid
== p
->pid
&&
3604 i
->start_timestamp
== p
->start_timestamp
&&
3605 i
->exit_timestamp
== p
->start_timestamp
)
3606 /* Let's not show this twice */
3609 if (p
->pid
== i
->control_pid
)
3613 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3614 if (i
->main_pid
> 0) {
3615 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3618 _cleanup_free_
char *comm
= NULL
;
3619 get_process_comm(i
->main_pid
, &comm
);
3621 printf(" (%s)", comm
);
3622 } else if (i
->exit_code
> 0) {
3623 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3625 if (i
->exit_code
== CLD_EXITED
) {
3628 printf("status=%i", i
->exit_status
);
3630 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3635 printf("signal=%s", signal_to_string(i
->exit_status
));
3639 if (i
->control_pid
> 0)
3643 if (i
->control_pid
> 0) {
3644 _cleanup_free_
char *c
= NULL
;
3646 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3648 get_process_comm(i
->control_pid
, &c
);
3657 printf(" Status: \"%s\"\n", i
->status_text
);
3658 if (i
->status_errno
> 0)
3659 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3661 if (i
->tasks_current
!= (uint64_t) -1) {
3662 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3664 if (i
->tasks_max
!= (uint64_t) -1)
3665 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3670 if (i
->memory_current
!= (uint64_t) -1) {
3671 char buf
[FORMAT_BYTES_MAX
];
3673 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3675 if (i
->memory_limit
!= (uint64_t) -1)
3676 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3681 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3682 char buf
[FORMAT_TIMESPAN_MAX
];
3683 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3686 if (i
->control_group
&&
3687 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3688 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3691 printf(" CGroup: %s\n", i
->control_group
);
3693 if (IN_SET(arg_transport
,
3694 BUS_TRANSPORT_LOCAL
,
3695 BUS_TRANSPORT_MACHINE
)) {
3698 static const char prefix
[] = " ";
3701 if (c
> sizeof(prefix
) - 1)
3702 c
-= sizeof(prefix
) - 1;
3706 if (i
->main_pid
> 0)
3707 extra
[k
++] = i
->main_pid
;
3709 if (i
->control_pid
> 0)
3710 extra
[k
++] = i
->control_pid
;
3712 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3716 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3717 show_journal_by_unit(
3722 i
->inactive_exit_timestamp_monotonic
,
3725 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3726 SD_JOURNAL_LOCAL_ONLY
,
3727 arg_scope
== UNIT_FILE_SYSTEM
,
3730 if (i
->need_daemon_reload
)
3731 warn_unit_file_changed(i
->id
);
3734 static void show_unit_help(UnitStatusInfo
*i
) {
3739 if (!i
->documentation
) {
3740 log_info("Documentation for %s not known.", i
->id
);
3744 STRV_FOREACH(p
, i
->documentation
)
3745 if (startswith(*p
, "man:"))
3746 show_man_page(*p
+ 4, false);
3748 log_info("Can't show: %s", *p
);
3751 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3758 switch (contents
[0]) {
3760 case SD_BUS_TYPE_STRING
: {
3763 r
= sd_bus_message_read(m
, "s", &s
);
3765 return bus_log_parse_error(r
);
3768 if (streq(name
, "Id"))
3770 else if (streq(name
, "LoadState"))
3772 else if (streq(name
, "ActiveState"))
3773 i
->active_state
= s
;
3774 else if (streq(name
, "SubState"))
3776 else if (streq(name
, "Description"))
3778 else if (streq(name
, "FragmentPath"))
3779 i
->fragment_path
= s
;
3780 else if (streq(name
, "SourcePath"))
3783 else if (streq(name
, "DefaultControlGroup")) {
3785 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3787 i
->control_group
= e
;
3790 else if (streq(name
, "ControlGroup"))
3791 i
->control_group
= s
;
3792 else if (streq(name
, "StatusText"))
3794 else if (streq(name
, "PIDFile"))
3796 else if (streq(name
, "SysFSPath"))
3798 else if (streq(name
, "Where"))
3800 else if (streq(name
, "What"))
3802 else if (streq(name
, "Following"))
3804 else if (streq(name
, "UnitFileState"))
3805 i
->unit_file_state
= s
;
3806 else if (streq(name
, "UnitFilePreset"))
3807 i
->unit_file_preset
= s
;
3808 else if (streq(name
, "Result"))
3815 case SD_BUS_TYPE_BOOLEAN
: {
3818 r
= sd_bus_message_read(m
, "b", &b
);
3820 return bus_log_parse_error(r
);
3822 if (streq(name
, "Accept"))
3824 else if (streq(name
, "NeedDaemonReload"))
3825 i
->need_daemon_reload
= b
;
3826 else if (streq(name
, "ConditionResult"))
3827 i
->condition_result
= b
;
3828 else if (streq(name
, "AssertResult"))
3829 i
->assert_result
= b
;
3834 case SD_BUS_TYPE_UINT32
: {
3837 r
= sd_bus_message_read(m
, "u", &u
);
3839 return bus_log_parse_error(r
);
3841 if (streq(name
, "MainPID")) {
3843 i
->main_pid
= (pid_t
) u
;
3846 } else if (streq(name
, "ControlPID"))
3847 i
->control_pid
= (pid_t
) u
;
3848 else if (streq(name
, "ExecMainPID")) {
3850 i
->main_pid
= (pid_t
) u
;
3851 } else if (streq(name
, "NAccepted"))
3853 else if (streq(name
, "NConnections"))
3854 i
->n_connections
= u
;
3859 case SD_BUS_TYPE_INT32
: {
3862 r
= sd_bus_message_read(m
, "i", &j
);
3864 return bus_log_parse_error(r
);
3866 if (streq(name
, "ExecMainCode"))
3867 i
->exit_code
= (int) j
;
3868 else if (streq(name
, "ExecMainStatus"))
3869 i
->exit_status
= (int) j
;
3870 else if (streq(name
, "StatusErrno"))
3871 i
->status_errno
= (int) j
;
3876 case SD_BUS_TYPE_UINT64
: {
3879 r
= sd_bus_message_read(m
, "t", &u
);
3881 return bus_log_parse_error(r
);
3883 if (streq(name
, "ExecMainStartTimestamp"))
3884 i
->start_timestamp
= (usec_t
) u
;
3885 else if (streq(name
, "ExecMainExitTimestamp"))
3886 i
->exit_timestamp
= (usec_t
) u
;
3887 else if (streq(name
, "ActiveEnterTimestamp"))
3888 i
->active_enter_timestamp
= (usec_t
) u
;
3889 else if (streq(name
, "InactiveEnterTimestamp"))
3890 i
->inactive_enter_timestamp
= (usec_t
) u
;
3891 else if (streq(name
, "InactiveExitTimestamp"))
3892 i
->inactive_exit_timestamp
= (usec_t
) u
;
3893 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3894 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3895 else if (streq(name
, "ActiveExitTimestamp"))
3896 i
->active_exit_timestamp
= (usec_t
) u
;
3897 else if (streq(name
, "ConditionTimestamp"))
3898 i
->condition_timestamp
= (usec_t
) u
;
3899 else if (streq(name
, "AssertTimestamp"))
3900 i
->assert_timestamp
= (usec_t
) u
;
3901 else if (streq(name
, "MemoryCurrent"))
3902 i
->memory_current
= u
;
3903 else if (streq(name
, "MemoryLimit"))
3904 i
->memory_limit
= u
;
3905 else if (streq(name
, "TasksCurrent"))
3906 i
->tasks_current
= u
;
3907 else if (streq(name
, "TasksMax"))
3909 else if (streq(name
, "CPUUsageNSec"))
3910 i
->cpu_usage_nsec
= u
;
3915 case SD_BUS_TYPE_ARRAY
:
3917 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3918 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3920 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3922 return bus_log_parse_error(r
);
3924 info
= new0(ExecStatusInfo
, 1);
3928 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3930 info
->name
= strdup(name
);
3934 LIST_PREPEND(exec
, i
->exec
, info
);
3936 info
= new0(ExecStatusInfo
, 1);
3942 return bus_log_parse_error(r
);
3944 r
= sd_bus_message_exit_container(m
);
3946 return bus_log_parse_error(r
);
3950 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3951 const char *type
, *path
;
3953 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3955 return bus_log_parse_error(r
);
3957 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3959 r
= strv_extend(&i
->listen
, type
);
3963 r
= strv_extend(&i
->listen
, path
);
3968 return bus_log_parse_error(r
);
3970 r
= sd_bus_message_exit_container(m
);
3972 return bus_log_parse_error(r
);
3976 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3978 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3980 return bus_log_parse_error(r
);
3982 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3984 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3986 return bus_log_parse_error(r
);
3988 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3989 const char *cond
, *param
;
3990 int trigger
, negate
;
3993 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3995 return bus_log_parse_error(r
);
3997 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3998 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3999 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4000 i
->failed_condition
= cond
;
4001 i
->failed_condition_trigger
= trigger
;
4002 i
->failed_condition_negate
= negate
;
4003 i
->failed_condition_parameter
= param
;
4007 return bus_log_parse_error(r
);
4009 r
= sd_bus_message_exit_container(m
);
4011 return bus_log_parse_error(r
);
4013 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4014 const char *cond
, *param
;
4015 int trigger
, negate
;
4018 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4020 return bus_log_parse_error(r
);
4022 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4023 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4024 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4025 i
->failed_assert
= cond
;
4026 i
->failed_assert_trigger
= trigger
;
4027 i
->failed_assert_negate
= negate
;
4028 i
->failed_assert_parameter
= param
;
4032 return bus_log_parse_error(r
);
4034 r
= sd_bus_message_exit_container(m
);
4036 return bus_log_parse_error(r
);
4043 case SD_BUS_TYPE_STRUCT_BEGIN
:
4045 if (streq(name
, "LoadError")) {
4046 const char *n
, *message
;
4048 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4050 return bus_log_parse_error(r
);
4052 if (!isempty(message
))
4053 i
->load_error
= message
;
4066 r
= sd_bus_message_skip(m
, contents
);
4068 return bus_log_parse_error(r
);
4073 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4079 /* This is a low-level property printer, see
4080 * print_status_info() for the nicer output */
4082 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4083 /* skip what we didn't read */
4084 r
= sd_bus_message_skip(m
, contents
);
4088 switch (contents
[0]) {
4090 case SD_BUS_TYPE_STRUCT_BEGIN
:
4092 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4095 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4097 return bus_log_parse_error(r
);
4100 printf("%s=%"PRIu32
"\n", name
, u
);
4102 printf("%s=\n", name
);
4106 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4109 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4111 return bus_log_parse_error(r
);
4113 if (arg_all
|| !isempty(s
))
4114 printf("%s=%s\n", name
, s
);
4118 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4119 const char *a
= NULL
, *b
= NULL
;
4121 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4123 return bus_log_parse_error(r
);
4125 if (arg_all
|| !isempty(a
) || !isempty(b
))
4126 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4129 } else if (streq_ptr(name
, "SystemCallFilter")) {
4130 _cleanup_strv_free_
char **l
= NULL
;
4133 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4135 return bus_log_parse_error(r
);
4137 r
= sd_bus_message_read(m
, "b", &whitelist
);
4139 return bus_log_parse_error(r
);
4141 r
= sd_bus_message_read_strv(m
, &l
);
4143 return bus_log_parse_error(r
);
4145 r
= sd_bus_message_exit_container(m
);
4147 return bus_log_parse_error(r
);
4149 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4153 fputs(name
, stdout
);
4159 STRV_FOREACH(i
, l
) {
4167 fputc('\n', stdout
);
4175 case SD_BUS_TYPE_ARRAY
:
4177 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4181 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4183 return bus_log_parse_error(r
);
4185 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4186 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4189 return bus_log_parse_error(r
);
4191 r
= sd_bus_message_exit_container(m
);
4193 return bus_log_parse_error(r
);
4197 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4198 const char *type
, *path
;
4200 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4202 return bus_log_parse_error(r
);
4204 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4205 printf("%s=%s\n", type
, path
);
4207 return bus_log_parse_error(r
);
4209 r
= sd_bus_message_exit_container(m
);
4211 return bus_log_parse_error(r
);
4215 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4216 const char *type
, *path
;
4218 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4220 return bus_log_parse_error(r
);
4222 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4223 printf("Listen%s=%s\n", type
, path
);
4225 return bus_log_parse_error(r
);
4227 r
= sd_bus_message_exit_container(m
);
4229 return bus_log_parse_error(r
);
4233 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4235 uint64_t value
, next_elapse
;
4237 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4239 return bus_log_parse_error(r
);
4241 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4242 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4244 printf("%s={ value=%s ; next_elapse=%s }\n",
4246 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4247 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4250 return bus_log_parse_error(r
);
4252 r
= sd_bus_message_exit_container(m
);
4254 return bus_log_parse_error(r
);
4258 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4259 ExecStatusInfo info
= {};
4261 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4263 return bus_log_parse_error(r
);
4265 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4266 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4267 _cleanup_free_
char *tt
;
4269 tt
= strv_join(info
.argv
, " ");
4271 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",
4275 yes_no(info
.ignore
),
4276 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4277 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4279 sigchld_code_to_string(info
.code
),
4281 info
.code
== CLD_EXITED
? "" : "/",
4282 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4285 strv_free(info
.argv
);
4289 r
= sd_bus_message_exit_container(m
);
4291 return bus_log_parse_error(r
);
4295 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4296 const char *path
, *rwm
;
4298 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4300 return bus_log_parse_error(r
);
4302 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4303 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4305 return bus_log_parse_error(r
);
4307 r
= sd_bus_message_exit_container(m
);
4309 return bus_log_parse_error(r
);
4313 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4317 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4319 return bus_log_parse_error(r
);
4321 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4322 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4324 return bus_log_parse_error(r
);
4326 r
= sd_bus_message_exit_container(m
);
4328 return bus_log_parse_error(r
);
4332 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4336 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4338 return bus_log_parse_error(r
);
4340 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4341 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4343 return bus_log_parse_error(r
);
4345 r
= sd_bus_message_exit_container(m
);
4347 return bus_log_parse_error(r
);
4355 r
= bus_print_property(name
, m
, arg_all
);
4357 return bus_log_parse_error(r
);
4360 r
= sd_bus_message_skip(m
, contents
);
4362 return bus_log_parse_error(r
);
4365 printf("%s=[unprintable]\n", name
);
4371 static int show_one(
4375 bool show_properties
,
4379 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4380 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4381 UnitStatusInfo info
= {
4382 .memory_current
= (uint64_t) -1,
4383 .memory_limit
= (uint64_t) -1,
4384 .cpu_usage_nsec
= (uint64_t) -1,
4385 .tasks_current
= (uint64_t) -1,
4386 .tasks_max
= (uint64_t) -1,
4394 log_debug("Showing one %s", path
);
4396 r
= sd_bus_call_method(
4398 "org.freedesktop.systemd1",
4400 "org.freedesktop.DBus.Properties",
4406 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4408 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4410 return bus_log_parse_error(r
);
4417 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4418 const char *name
, *contents
;
4420 r
= sd_bus_message_read(reply
, "s", &name
);
4422 return bus_log_parse_error(r
);
4424 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4426 return bus_log_parse_error(r
);
4428 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4430 return bus_log_parse_error(r
);
4432 if (show_properties
)
4433 r
= print_property(name
, reply
, contents
);
4435 r
= status_property(name
, reply
, &info
, contents
);
4439 r
= sd_bus_message_exit_container(reply
);
4441 return bus_log_parse_error(r
);
4443 r
= sd_bus_message_exit_container(reply
);
4445 return bus_log_parse_error(r
);
4448 return bus_log_parse_error(r
);
4450 r
= sd_bus_message_exit_container(reply
);
4452 return bus_log_parse_error(r
);
4456 if (!show_properties
) {
4457 if (streq(verb
, "help"))
4458 show_unit_help(&info
);
4460 print_status_info(&info
, ellipsized
);
4463 strv_free(info
.documentation
);
4464 strv_free(info
.dropin_paths
);
4465 strv_free(info
.listen
);
4467 if (!streq_ptr(info
.active_state
, "active") &&
4468 !streq_ptr(info
.active_state
, "reloading") &&
4469 streq(verb
, "status")) {
4470 /* According to LSB: "program not running" */
4471 /* 0: program is running or service is OK
4472 * 1: program is dead and /run PID file exists
4473 * 2: program is dead and /run/lock lock file exists
4474 * 3: program is not running
4475 * 4: program or service status is unknown
4477 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4483 while ((p
= info
.exec
)) {
4484 LIST_REMOVE(exec
, info
.exec
, p
);
4485 exec_status_info_free(p
);
4491 static int get_unit_dbus_path_by_pid(
4496 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4497 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4501 r
= sd_bus_call_method(
4503 "org.freedesktop.systemd1",
4504 "/org/freedesktop/systemd1",
4505 "org.freedesktop.systemd1.Manager",
4511 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4513 r
= sd_bus_message_read(reply
, "o", &u
);
4515 return bus_log_parse_error(r
);
4525 static int show_all(
4528 bool show_properties
,
4532 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4533 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4538 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4542 pager_open_if_enabled();
4546 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4548 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4549 _cleanup_free_
char *p
= NULL
;
4551 p
= unit_dbus_path_from_name(u
->id
);
4555 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4558 else if (r
> 0 && ret
== 0)
4565 static int show_system_status(sd_bus
*bus
) {
4566 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4567 _cleanup_free_
char *hn
= NULL
;
4568 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4569 const char *on
, *off
;
4572 hn
= gethostname_malloc();
4576 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4578 return log_error_errno(r
, "Failed to read server status: %m");
4580 if (streq_ptr(mi
.state
, "degraded")) {
4581 on
= ansi_highlight_red();
4582 off
= ansi_normal();
4583 } else if (!streq_ptr(mi
.state
, "running")) {
4584 on
= ansi_highlight_yellow();
4585 off
= ansi_normal();
4589 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4591 printf(" State: %s%s%s\n",
4592 on
, strna(mi
.state
), off
);
4594 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4595 printf(" Failed: %u units\n", mi
.n_failed_units
);
4597 printf(" Since: %s; %s\n",
4598 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4599 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4601 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4602 if (IN_SET(arg_transport
,
4603 BUS_TRANSPORT_LOCAL
,
4604 BUS_TRANSPORT_MACHINE
)) {
4605 static const char prefix
[] = " ";
4609 if (c
> sizeof(prefix
) - 1)
4610 c
-= sizeof(prefix
) - 1;
4614 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4620 static int show(int argc
, char *argv
[], void *userdata
) {
4621 bool show_properties
, show_status
, show_help
, new_line
= false;
4622 bool ellipsized
= false;
4628 show_properties
= streq(argv
[0], "show");
4629 show_status
= streq(argv
[0], "status");
4630 show_help
= streq(argv
[0], "help");
4632 if (show_help
&& argc
<= 1) {
4633 log_error("This command expects one or more unit names. Did you mean --help?");
4637 if (show_properties
)
4638 pager_open_if_enabled();
4641 /* Increase max number of open files to 16K if we can, we
4642 * might needs this when browsing journal files, which might
4643 * be split up into many files. */
4644 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4646 r
= acquire_bus(BUS_MANAGER
, &bus
);
4650 /* If no argument is specified inspect the manager itself */
4651 if (show_properties
&& argc
<= 1)
4652 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4654 if (show_status
&& argc
<= 1) {
4656 pager_open_if_enabled();
4657 show_system_status(bus
);
4661 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4663 _cleanup_free_
char **patterns
= NULL
;
4666 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4667 _cleanup_free_
char *unit
= NULL
;
4670 if (safe_atou32(*name
, &id
) < 0) {
4671 if (strv_push(&patterns
, *name
) < 0)
4675 } else if (show_properties
) {
4676 /* Interpret as job id */
4677 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4681 /* Interpret as PID */
4682 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4689 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4692 else if (r
> 0 && ret
== 0)
4696 if (!strv_isempty(patterns
)) {
4697 _cleanup_strv_free_
char **names
= NULL
;
4699 r
= expand_names(bus
, patterns
, NULL
, &names
);
4701 return log_error_errno(r
, "Failed to expand names: %m");
4703 STRV_FOREACH(name
, names
) {
4704 _cleanup_free_
char *unit
;
4706 unit
= unit_dbus_path_from_name(*name
);
4710 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4713 else if (r
> 0 && ret
== 0)
4719 if (ellipsized
&& !arg_quiet
)
4720 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4725 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4729 assert(user_runtime
);
4732 if (arg_scope
== UNIT_FILE_USER
) {
4733 r
= user_config_home(user_home
);
4735 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4737 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4739 r
= user_runtime_dir(user_runtime
);
4741 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4743 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4746 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4748 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4753 static int cat_file(const char *filename
, bool newline
) {
4754 _cleanup_close_
int fd
;
4756 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4760 printf("%s%s# %s%s\n",
4761 newline
? "\n" : "",
4762 ansi_highlight_blue(),
4767 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4770 static int cat(int argc
, char *argv
[], void *userdata
) {
4771 _cleanup_free_
char *user_home
= NULL
;
4772 _cleanup_free_
char *user_runtime
= NULL
;
4773 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4774 _cleanup_strv_free_
char **names
= NULL
;
4780 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4781 log_error("Cannot remotely cat units.");
4785 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4789 r
= acquire_bus(BUS_MANAGER
, &bus
);
4793 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4795 return log_error_errno(r
, "Failed to expand names: %m");
4797 pager_open_if_enabled();
4799 STRV_FOREACH(name
, names
) {
4800 _cleanup_free_
char *fragment_path
= NULL
;
4801 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4804 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4815 if (fragment_path
) {
4816 r
= cat_file(fragment_path
, false);
4818 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4821 STRV_FOREACH(path
, dropin_paths
) {
4822 r
= cat_file(*path
, path
== dropin_paths
);
4824 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4831 static int set_property(int argc
, char *argv
[], void *userdata
) {
4832 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4833 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4834 _cleanup_free_
char *n
= NULL
;
4839 polkit_agent_open_if_enabled();
4841 r
= acquire_bus(BUS_MANAGER
, &bus
);
4845 r
= sd_bus_message_new_method_call(
4848 "org.freedesktop.systemd1",
4849 "/org/freedesktop/systemd1",
4850 "org.freedesktop.systemd1.Manager",
4851 "SetUnitProperties");
4853 return bus_log_create_error(r
);
4855 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4857 return log_error_errno(r
, "Failed to mangle unit name: %m");
4859 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4861 return bus_log_create_error(r
);
4863 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4865 return bus_log_create_error(r
);
4867 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4868 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4870 return bus_log_create_error(r
);
4872 r
= bus_append_unit_property_assignment(m
, *i
);
4876 r
= sd_bus_message_close_container(m
);
4878 return bus_log_create_error(r
);
4881 r
= sd_bus_message_close_container(m
);
4883 return bus_log_create_error(r
);
4885 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4887 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4892 static int snapshot(int argc
, char *argv
[], void *userdata
) {
4893 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4894 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4895 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4900 polkit_agent_open_if_enabled();
4903 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4905 return log_error_errno(r
, "Failed to generate unit name: %m");
4912 r
= acquire_bus(BUS_MANAGER
, &bus
);
4916 r
= sd_bus_call_method(
4918 "org.freedesktop.systemd1",
4919 "/org/freedesktop/systemd1",
4920 "org.freedesktop.systemd1.Manager",
4926 return log_error_errno(r
, "Failed to create snapshot: %s", bus_error_message(&error
, r
));
4928 r
= sd_bus_message_read(reply
, "o", &path
);
4930 return bus_log_parse_error(r
);
4932 r
= sd_bus_get_property_string(
4934 "org.freedesktop.systemd1",
4936 "org.freedesktop.systemd1.Unit",
4941 return log_error_errno(r
, "Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4949 static int delete_snapshot(int argc
, char *argv
[], void *userdata
) {
4950 _cleanup_strv_free_
char **names
= NULL
;
4955 polkit_agent_open_if_enabled();
4957 r
= acquire_bus(BUS_MANAGER
, &bus
);
4961 r
= expand_names(bus
, strv_skip(argv
, 1), ".snapshot", &names
);
4963 return log_error_errno(r
, "Failed to expand names: %m");
4965 STRV_FOREACH(name
, names
) {
4966 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4969 q
= sd_bus_call_method(
4971 "org.freedesktop.systemd1",
4972 "/org/freedesktop/systemd1",
4973 "org.freedesktop.systemd1.Manager",
4979 log_error_errno(q
, "Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4988 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4989 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4994 polkit_agent_open_if_enabled();
4996 r
= acquire_bus(BUS_MANAGER
, &bus
);
5000 if (arg_action
== ACTION_RELOAD
)
5002 else if (arg_action
== ACTION_REEXEC
)
5003 method
= "Reexecute";
5005 assert(arg_action
== ACTION_SYSTEMCTL
);
5008 streq(argv
[0], "clear-jobs") ||
5009 streq(argv
[0], "cancel") ? "ClearJobs" :
5010 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5011 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5012 streq(argv
[0], "halt") ? "Halt" :
5013 streq(argv
[0], "poweroff") ? "PowerOff" :
5014 streq(argv
[0], "reboot") ? "Reboot" :
5015 streq(argv
[0], "kexec") ? "KExec" :
5016 streq(argv
[0], "exit") ? "Exit" :
5017 /* "daemon-reload" */ "Reload";
5020 r
= sd_bus_call_method(
5022 "org.freedesktop.systemd1",
5023 "/org/freedesktop/systemd1",
5024 "org.freedesktop.systemd1.Manager",
5029 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
5030 /* There's always a fallback possible for
5031 * legacy actions. */
5033 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
5034 /* On reexecution, we expect a disconnect, not a
5038 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5040 return r
< 0 ? r
: 0;
5043 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5044 _cleanup_strv_free_
char **names
= NULL
;
5050 return daemon_reload(argc
, argv
, userdata
);
5052 polkit_agent_open_if_enabled();
5054 r
= acquire_bus(BUS_MANAGER
, &bus
);
5058 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5060 return log_error_errno(r
, "Failed to expand names: %m");
5062 STRV_FOREACH(name
, names
) {
5063 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5065 q
= sd_bus_call_method(
5067 "org.freedesktop.systemd1",
5068 "/org/freedesktop/systemd1",
5069 "org.freedesktop.systemd1.Manager",
5075 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5084 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5085 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5086 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5091 pager_open_if_enabled();
5093 r
= acquire_bus(BUS_MANAGER
, &bus
);
5097 r
= sd_bus_get_property(
5099 "org.freedesktop.systemd1",
5100 "/org/freedesktop/systemd1",
5101 "org.freedesktop.systemd1.Manager",
5107 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5109 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5111 return bus_log_parse_error(r
);
5113 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5116 return bus_log_parse_error(r
);
5118 r
= sd_bus_message_exit_container(reply
);
5120 return bus_log_parse_error(r
);
5125 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5126 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5127 _cleanup_free_
char *cmdline_init
= NULL
;
5128 const char *root
, *init
;
5132 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5133 log_error("Cannot switch root remotely.");
5137 if (argc
< 2 || argc
> 3) {
5138 log_error("Wrong number of arguments.");
5147 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5148 "init", &cmdline_init
,
5151 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5153 init
= cmdline_init
;
5160 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5162 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5163 root_init_path
= strjoina(root
, "/", init
);
5165 /* If the passed init is actually the same as the
5166 * systemd binary, then let's suppress it. */
5167 if (files_same(root_init_path
, root_systemd_path
) > 0)
5171 r
= acquire_bus(BUS_MANAGER
, &bus
);
5175 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5177 r
= sd_bus_call_method(
5179 "org.freedesktop.systemd1",
5180 "/org/freedesktop/systemd1",
5181 "org.freedesktop.systemd1.Manager",
5187 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5192 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5193 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5194 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5202 polkit_agent_open_if_enabled();
5204 r
= acquire_bus(BUS_MANAGER
, &bus
);
5208 method
= streq(argv
[0], "set-environment")
5210 : "UnsetEnvironment";
5212 r
= sd_bus_message_new_method_call(
5215 "org.freedesktop.systemd1",
5216 "/org/freedesktop/systemd1",
5217 "org.freedesktop.systemd1.Manager",
5220 return bus_log_create_error(r
);
5222 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5224 return bus_log_create_error(r
);
5226 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5228 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5233 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5234 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5235 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5239 polkit_agent_open_if_enabled();
5241 r
= acquire_bus(BUS_MANAGER
, &bus
);
5245 r
= sd_bus_message_new_method_call(
5248 "org.freedesktop.systemd1",
5249 "/org/freedesktop/systemd1",
5250 "org.freedesktop.systemd1.Manager",
5253 return bus_log_create_error(r
);
5256 r
= sd_bus_message_append_strv(m
, environ
);
5260 r
= sd_bus_message_open_container(m
, 'a', "s");
5262 return bus_log_create_error(r
);
5264 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5266 if (!env_name_is_valid(*a
)) {
5267 log_error("Not a valid environment variable name: %s", *a
);
5271 STRV_FOREACH(b
, environ
) {
5274 eq
= startswith(*b
, *a
);
5275 if (eq
&& *eq
== '=') {
5277 r
= sd_bus_message_append(m
, "s", *b
);
5279 return bus_log_create_error(r
);
5286 r
= sd_bus_message_close_container(m
);
5289 return bus_log_create_error(r
);
5291 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5293 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5298 static int enable_sysv_units(const char *verb
, char **args
) {
5301 #if defined(HAVE_SYSV_COMPAT)
5303 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5305 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5308 if (!STR_IN_SET(verb
,
5314 /* Processes all SysV units, and reshuffles the array so that
5315 * afterwards only the native units remain */
5317 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5324 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5325 bool found_native
= false, found_sysv
;
5327 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5335 if (!endswith(name
, ".service"))
5338 if (path_is_absolute(name
))
5341 STRV_FOREACH(k
, paths
.unit_path
) {
5342 _cleanup_free_
char *path
= NULL
;
5344 path
= path_join(arg_root
, *k
, name
);
5348 found_native
= access(path
, F_OK
) >= 0;
5353 /* If we have both a native unit and a SysV script,
5354 * enable/disable them both (below); for is-enabled, prefer the
5356 if (found_native
&& streq(verb
, "is-enabled"))
5359 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5363 p
[strlen(p
) - strlen(".service")] = 0;
5364 found_sysv
= access(p
, F_OK
) >= 0;
5369 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5371 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5373 if (!isempty(arg_root
))
5374 argv
[c
++] = q
= strappend("--root=", arg_root
);
5377 argv
[c
++] = basename(p
);
5380 l
= strv_join((char**)argv
, " ");
5384 log_info("Executing %s", l
);
5388 return log_error_errno(errno
, "Failed to fork: %m");
5389 else if (pid
== 0) {
5392 (void) reset_all_signal_handlers();
5393 (void) reset_signal_mask();
5395 execv(argv
[0], (char**) argv
);
5396 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5397 _exit(EXIT_FAILURE
);
5400 j
= wait_for_terminate(pid
, &status
);
5402 log_error_errno(j
, "Failed to wait for child: %m");
5406 if (status
.si_code
== CLD_EXITED
) {
5407 if (streq(verb
, "is-enabled")) {
5408 if (status
.si_status
== 0) {
5417 } else if (status
.si_status
!= 0)
5425 /* Remove this entry, so that we don't try enabling it as native unit */
5428 assert(args
[f
] == name
);
5429 strv_remove(args
, name
);
5436 static int mangle_names(char **original_names
, char ***mangled_names
) {
5437 char **i
, **l
, **name
;
5440 l
= i
= new(char*, strv_length(original_names
) + 1);
5444 STRV_FOREACH(name
, original_names
) {
5446 /* When enabling units qualified path names are OK,
5447 * too, hence allow them explicitly. */
5449 if (is_path(*name
)) {
5456 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5459 return log_error_errno(r
, "Failed to mangle unit name: %m");
5472 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5473 _cleanup_strv_free_
char **names
= NULL
;
5474 const char *verb
= argv
[0];
5475 UnitFileChange
*changes
= NULL
;
5476 unsigned n_changes
= 0;
5477 int carries_install_info
= -1;
5483 r
= mangle_names(strv_skip(argv
, 1), &names
);
5487 r
= enable_sysv_units(verb
, names
);
5491 /* If the operation was fully executed by the SysV compat,
5492 * let's finish early */
5493 if (strv_isempty(names
))
5496 if (install_client_side()) {
5497 if (streq(verb
, "enable")) {
5498 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5499 carries_install_info
= r
;
5500 } else if (streq(verb
, "disable"))
5501 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5502 else if (streq(verb
, "reenable")) {
5503 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5504 carries_install_info
= r
;
5505 } else if (streq(verb
, "link"))
5506 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5507 else if (streq(verb
, "preset")) {
5508 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5509 carries_install_info
= r
;
5510 } else if (streq(verb
, "mask"))
5511 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5512 else if (streq(verb
, "unmask"))
5513 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5515 assert_not_reached("Unknown verb");
5518 log_error_errno(r
, "Operation failed: %m");
5523 dump_unit_file_changes(changes
, n_changes
);
5527 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5528 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5529 int expect_carries_install_info
= false;
5530 bool send_force
= true, send_preset_mode
= false;
5534 polkit_agent_open_if_enabled();
5536 r
= acquire_bus(BUS_MANAGER
, &bus
);
5540 if (streq(verb
, "enable")) {
5541 method
= "EnableUnitFiles";
5542 expect_carries_install_info
= true;
5543 } else if (streq(verb
, "disable")) {
5544 method
= "DisableUnitFiles";
5546 } else if (streq(verb
, "reenable")) {
5547 method
= "ReenableUnitFiles";
5548 expect_carries_install_info
= true;
5549 } else if (streq(verb
, "link"))
5550 method
= "LinkUnitFiles";
5551 else if (streq(verb
, "preset")) {
5553 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5554 method
= "PresetUnitFilesWithMode";
5555 send_preset_mode
= true;
5557 method
= "PresetUnitFiles";
5559 expect_carries_install_info
= true;
5560 } else if (streq(verb
, "mask"))
5561 method
= "MaskUnitFiles";
5562 else if (streq(verb
, "unmask")) {
5563 method
= "UnmaskUnitFiles";
5566 assert_not_reached("Unknown verb");
5568 r
= sd_bus_message_new_method_call(
5571 "org.freedesktop.systemd1",
5572 "/org/freedesktop/systemd1",
5573 "org.freedesktop.systemd1.Manager",
5576 return bus_log_create_error(r
);
5578 r
= sd_bus_message_append_strv(m
, names
);
5580 return bus_log_create_error(r
);
5582 if (send_preset_mode
) {
5583 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5585 return bus_log_create_error(r
);
5588 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5590 return bus_log_create_error(r
);
5593 r
= sd_bus_message_append(m
, "b", arg_force
);
5595 return bus_log_create_error(r
);
5598 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5600 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5602 if (expect_carries_install_info
) {
5603 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5605 return bus_log_parse_error(r
);
5608 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5612 /* Try to reload if enabled */
5614 r
= daemon_reload(argc
, argv
, userdata
);
5619 if (carries_install_info
== 0)
5620 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5621 "using systemctl.\n"
5622 "Possible reasons for having this kind of units are:\n"
5623 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5624 " .wants/ or .requires/ directory.\n"
5625 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5626 " a requirement dependency on it.\n"
5627 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5628 " D-Bus, udev, scripted systemctl call, ...).\n");
5630 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5631 char *new_args
[n_changes
+ 2];
5635 r
= acquire_bus(BUS_MANAGER
, &bus
);
5639 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5640 for (i
= 0; i
< n_changes
; i
++)
5641 new_args
[i
+ 1] = basename(changes
[i
].path
);
5642 new_args
[i
+ 1] = NULL
;
5644 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5648 unit_file_changes_free(changes
, n_changes
);
5653 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5654 _cleanup_strv_free_
char **names
= NULL
;
5655 _cleanup_free_
char *target
= NULL
;
5656 const char *verb
= argv
[0];
5663 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5665 return log_error_errno(r
, "Failed to mangle unit name: %m");
5667 r
= mangle_names(strv_skip(argv
, 2), &names
);
5671 if (streq(verb
, "add-wants"))
5673 else if (streq(verb
, "add-requires"))
5674 dep
= UNIT_REQUIRES
;
5676 assert_not_reached("Unknown verb");
5678 if (install_client_side()) {
5679 UnitFileChange
*changes
= NULL
;
5680 unsigned n_changes
= 0;
5682 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5685 return log_error_errno(r
, "Can't add dependency: %m");
5688 dump_unit_file_changes(changes
, n_changes
);
5690 unit_file_changes_free(changes
, n_changes
);
5693 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5694 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5697 polkit_agent_open_if_enabled();
5699 r
= acquire_bus(BUS_MANAGER
, &bus
);
5703 r
= sd_bus_message_new_method_call(
5706 "org.freedesktop.systemd1",
5707 "/org/freedesktop/systemd1",
5708 "org.freedesktop.systemd1.Manager",
5709 "AddDependencyUnitFiles");
5711 return bus_log_create_error(r
);
5713 r
= sd_bus_message_append_strv(m
, names
);
5715 return bus_log_create_error(r
);
5717 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5719 return bus_log_create_error(r
);
5721 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5723 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5725 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5730 r
= daemon_reload(argc
, argv
, userdata
);
5738 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5739 UnitFileChange
*changes
= NULL
;
5740 unsigned n_changes
= 0;
5743 if (install_client_side()) {
5745 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5747 log_error_errno(r
, "Operation failed: %m");
5752 dump_unit_file_changes(changes
, n_changes
);
5757 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5758 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5761 polkit_agent_open_if_enabled();
5763 r
= acquire_bus(BUS_MANAGER
, &bus
);
5767 r
= sd_bus_call_method(
5769 "org.freedesktop.systemd1",
5770 "/org/freedesktop/systemd1",
5771 "org.freedesktop.systemd1.Manager",
5772 "PresetAllUnitFiles",
5776 unit_file_preset_mode_to_string(arg_preset_mode
),
5780 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5782 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5787 r
= daemon_reload(argc
, argv
, userdata
);
5793 unit_file_changes_free(changes
, n_changes
);
5798 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5800 _cleanup_strv_free_
char **names
= NULL
;
5805 r
= mangle_names(strv_skip(argv
, 1), &names
);
5809 r
= enable_sysv_units(argv
[0], names
);
5815 if (install_client_side()) {
5817 STRV_FOREACH(name
, names
) {
5818 UnitFileState state
;
5820 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5822 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5826 UNIT_FILE_ENABLED_RUNTIME
,
5828 UNIT_FILE_INDIRECT
))
5832 puts(unit_file_state_to_string(state
));
5836 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5839 r
= acquire_bus(BUS_MANAGER
, &bus
);
5843 STRV_FOREACH(name
, names
) {
5844 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5847 r
= sd_bus_call_method(
5849 "org.freedesktop.systemd1",
5850 "/org/freedesktop/systemd1",
5851 "org.freedesktop.systemd1.Manager",
5857 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5859 r
= sd_bus_message_read(reply
, "s", &s
);
5861 return bus_log_parse_error(r
);
5863 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5874 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5875 _cleanup_free_
char *state
= NULL
;
5879 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5882 return EXIT_FAILURE
;
5885 r
= acquire_bus(BUS_MANAGER
, &bus
);
5889 r
= sd_bus_get_property_string(
5891 "org.freedesktop.systemd1",
5892 "/org/freedesktop/systemd1",
5893 "org.freedesktop.systemd1.Manager",
5906 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5909 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5910 _cleanup_free_
char *t
= NULL
;
5914 assert(original_path
);
5917 r
= tempfn_random(new_path
, NULL
, &t
);
5919 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5921 r
= mkdir_parents(new_path
, 0755);
5923 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5925 r
= copy_file(original_path
, t
, 0, 0644, 0);
5930 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5933 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5941 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5942 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5947 switch (arg_scope
) {
5948 case UNIT_FILE_SYSTEM
:
5949 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5951 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5953 case UNIT_FILE_GLOBAL
:
5954 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5956 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5958 case UNIT_FILE_USER
:
5960 assert(user_runtime
);
5962 path
= path_join(arg_root
, user_home
, name
);
5964 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5967 run
= path_join(arg_root
, user_runtime
, name
);
5971 assert_not_reached("Invalid scope");
5973 if (!path
|| (arg_runtime
&& !run
))
5977 if (access(path
, F_OK
) >= 0) {
5978 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5982 if (path2
&& access(path2
, F_OK
) >= 0) {
5983 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5997 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
) {
5998 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6002 assert(ret_new_path
);
6003 assert(ret_tmp_path
);
6005 ending
= strjoina(unit_name
, ".d/override.conf");
6006 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
6010 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6016 *ret_new_path
= tmp_new_path
;
6017 *ret_tmp_path
= tmp_tmp_path
;
6022 static int unit_file_create_copy(
6023 const char *unit_name
,
6024 const char *fragment_path
,
6025 const char *user_home
,
6026 const char *user_runtime
,
6027 char **ret_new_path
,
6028 char **ret_tmp_path
) {
6030 char *tmp_new_path
, *tmp_tmp_path
;
6033 assert(fragment_path
);
6035 assert(ret_new_path
);
6036 assert(ret_tmp_path
);
6038 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
6042 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6045 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6050 if (response
!= 'y') {
6051 log_warning("%s ignored", unit_name
);
6057 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6059 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6064 *ret_new_path
= tmp_new_path
;
6065 *ret_tmp_path
= tmp_tmp_path
;
6070 static int run_editor(char **paths
) {
6078 return log_error_errno(errno
, "Failed to fork: %m");
6082 char *editor
, **editor_args
= NULL
;
6083 char **tmp_path
, **original_path
, *p
;
6084 unsigned n_editor_args
= 0, i
= 1;
6087 (void) reset_all_signal_handlers();
6088 (void) reset_signal_mask();
6090 argc
= strv_length(paths
)/2 + 1;
6092 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6093 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6094 * we try to execute well known editors
6096 editor
= getenv("SYSTEMD_EDITOR");
6098 editor
= getenv("EDITOR");
6100 editor
= getenv("VISUAL");
6102 if (!isempty(editor
)) {
6103 editor_args
= strv_split(editor
, WHITESPACE
);
6106 _exit(EXIT_FAILURE
);
6108 n_editor_args
= strv_length(editor_args
);
6109 argc
+= n_editor_args
- 1;
6111 args
= newa(const char*, argc
+ 1);
6113 if (n_editor_args
> 0) {
6114 args
[0] = editor_args
[0];
6115 for (; i
< n_editor_args
; i
++)
6116 args
[i
] = editor_args
[i
];
6119 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6120 args
[i
] = *tmp_path
;
6125 if (n_editor_args
> 0)
6126 execvp(args
[0], (char* const*) args
);
6128 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6130 execvp(p
, (char* const*) args
);
6131 /* We do not fail if the editor doesn't exist
6132 * because we want to try each one of them before
6135 if (errno
!= ENOENT
) {
6136 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6137 _exit(EXIT_FAILURE
);
6141 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6142 _exit(EXIT_FAILURE
);
6145 r
= wait_for_terminate_and_warn("editor", pid
, true);
6147 return log_error_errno(r
, "Failed to wait for child: %m");
6152 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6153 _cleanup_free_
char *user_home
= NULL
;
6154 _cleanup_free_
char *user_runtime
= NULL
;
6155 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6162 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6166 STRV_FOREACH(name
, names
) {
6167 _cleanup_free_
char *path
= NULL
;
6168 char *new_path
, *tmp_path
;
6170 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6176 // FIXME: support units with path==NULL (no FragmentPath)
6177 log_error("No fragment exists for %s.", *name
);
6182 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6184 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6188 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6196 static int edit(int argc
, char *argv
[], void *userdata
) {
6197 _cleanup_strv_free_
char **names
= NULL
;
6198 _cleanup_strv_free_
char **paths
= NULL
;
6199 char **original
, **tmp
;
6204 log_error("Cannot edit units if not on a tty.");
6208 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6209 log_error("Cannot edit units remotely.");
6213 r
= acquire_bus(BUS_MANAGER
, &bus
);
6217 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6219 return log_error_errno(r
, "Failed to expand names: %m");
6221 r
= find_paths_to_edit(bus
, names
, &paths
);
6225 if (strv_isempty(paths
))
6228 r
= run_editor(paths
);
6232 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6233 /* If the temporary file is empty we ignore it. It's
6234 * useful if the user wants to cancel its modification
6236 if (null_or_empty_path(*tmp
)) {
6237 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6241 r
= rename(*tmp
, *original
);
6243 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6250 if (!arg_no_reload
&& !install_client_side())
6251 r
= daemon_reload(argc
, argv
, userdata
);
6254 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6255 (void) unlink(*tmp
);
6260 static void systemctl_help(void) {
6262 pager_open_if_enabled();
6264 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6265 "Query or send control commands to the systemd manager.\n\n"
6266 " -h --help Show this help\n"
6267 " --version Show package version\n"
6268 " --system Connect to system manager\n"
6269 " --user Connect to user service manager\n"
6270 " -H --host=[USER@]HOST\n"
6271 " Operate on remote host\n"
6272 " -M --machine=CONTAINER\n"
6273 " Operate on local container\n"
6274 " -t --type=TYPE List units of a particular type\n"
6275 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6276 " -p --property=NAME Show only properties by this name\n"
6277 " -a --all Show all loaded units/properties, including dead/empty\n"
6278 " ones. To list all units installed on the system, use\n"
6279 " the 'list-unit-files' command instead.\n"
6280 " -l --full Don't ellipsize unit names on output\n"
6281 " -r --recursive Show unit list of host and local containers\n"
6282 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6283 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6284 " queueing a new job\n"
6285 " --show-types When showing sockets, explicitly show their type\n"
6286 " -i --ignore-inhibitors\n"
6287 " When shutting down or sleeping, ignore inhibitors\n"
6288 " --kill-who=WHO Who to send signal to\n"
6289 " -s --signal=SIGNAL Which signal to send\n"
6290 " --now Start or stop unit in addition to enabling or disabling it\n"
6291 " -q --quiet Suppress output\n"
6292 " --no-block Do not wait until operation finished\n"
6293 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6294 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6295 " --no-legend Do not print a legend (column headers and hints)\n"
6296 " --no-pager Do not pipe output into a pager\n"
6297 " --no-ask-password\n"
6298 " Do not ask for system passwords\n"
6299 " --global Enable/disable unit files globally\n"
6300 " --runtime Enable unit files only temporarily until next reboot\n"
6301 " -f --force When enabling unit files, override existing symlinks\n"
6302 " When shutting down, execute action immediately\n"
6303 " --preset-mode= Apply only enable, only disable, or all presets\n"
6304 " --root=PATH Enable unit files in the specified root directory\n"
6305 " -n --lines=INTEGER Number of journal entries to show\n"
6306 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6307 " short-precise, short-monotonic, verbose,\n"
6308 " export, json, json-pretty, json-sse, cat)\n"
6309 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6310 " --plain Print unit dependencies as a list instead of a tree\n\n"
6312 " list-units [PATTERN...] List loaded units\n"
6313 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6314 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6315 " start NAME... Start (activate) one or more units\n"
6316 " stop NAME... Stop (deactivate) one or more units\n"
6317 " reload NAME... Reload one or more units\n"
6318 " restart NAME... Start or restart one or more units\n"
6319 " try-restart NAME... Restart one or more units if active\n"
6320 " reload-or-restart NAME... Reload one or more units if possible,\n"
6321 " otherwise start or restart\n"
6322 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6323 " otherwise restart if active\n"
6324 " isolate NAME Start one unit and stop all others\n"
6325 " kill NAME... Send signal to processes of a unit\n"
6326 " is-active PATTERN... Check whether units are active\n"
6327 " is-failed PATTERN... Check whether units are failed\n"
6328 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6329 " show [PATTERN...|JOB...] Show properties of one or more\n"
6330 " units/jobs or the manager\n"
6331 " cat PATTERN... Show files and drop-ins of one or more units\n"
6332 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6333 " help PATTERN...|PID... Show manual for one or more units\n"
6334 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6336 " list-dependencies [NAME] Recursively show units which are required\n"
6337 " or wanted by this unit or by which this\n"
6338 " unit is required or wanted\n\n"
6339 "Unit File Commands:\n"
6340 " list-unit-files [PATTERN...] List installed unit files\n"
6341 " enable NAME... Enable one or more unit files\n"
6342 " disable NAME... Disable one or more unit files\n"
6343 " reenable NAME... Reenable one or more unit files\n"
6344 " preset NAME... Enable/disable one or more unit files\n"
6345 " based on preset configuration\n"
6346 " preset-all Enable/disable all unit files based on\n"
6347 " preset configuration\n"
6348 " is-enabled NAME... Check whether unit files are enabled\n"
6349 " mask NAME... Mask one or more units\n"
6350 " unmask NAME... Unmask one or more units\n"
6351 " link PATH... Link one or more units files into\n"
6352 " the search path\n"
6353 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6354 " on specified one or more units\n"
6355 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6356 " on specified one or more units\n"
6357 " edit NAME... Edit one or more unit files\n"
6358 " get-default Get the name of the default target\n"
6359 " set-default NAME Set the default target\n\n"
6360 "Machine Commands:\n"
6361 " list-machines [PATTERN...] List local containers and host\n\n"
6363 " list-jobs [PATTERN...] List jobs\n"
6364 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6365 "Snapshot Commands:\n"
6366 " snapshot [NAME] Create a snapshot\n"
6367 " delete NAME... Remove one or more snapshots\n\n"
6368 "Environment Commands:\n"
6369 " show-environment Dump environment\n"
6370 " set-environment NAME=VALUE... Set one or more environment variables\n"
6371 " unset-environment NAME... Unset one or more environment variables\n"
6372 " import-environment [NAME...] Import all or some environment variables\n\n"
6373 "Manager Lifecycle Commands:\n"
6374 " daemon-reload Reload systemd manager configuration\n"
6375 " daemon-reexec Reexecute systemd manager\n\n"
6376 "System Commands:\n"
6377 " is-system-running Check whether system is fully running\n"
6378 " default Enter system default mode\n"
6379 " rescue Enter system rescue mode\n"
6380 " emergency Enter system emergency mode\n"
6381 " halt Shut down and halt the system\n"
6382 " poweroff Shut down and power-off the system\n"
6383 " reboot [ARG] Shut down and reboot the system\n"
6384 " kexec Shut down and reboot the system with kexec\n"
6385 " exit [EXIT_CODE] Request user instance or container exit\n"
6386 " switch-root ROOT [INIT] Change to a different root file system\n"
6387 " suspend Suspend the system\n"
6388 " hibernate Hibernate the system\n"
6389 " hybrid-sleep Hibernate and suspend the system\n",
6390 program_invocation_short_name
);
6393 static void halt_help(void) {
6394 printf("%s [OPTIONS...]%s\n\n"
6395 "%s the system.\n\n"
6396 " --help Show this help\n"
6397 " --halt Halt the machine\n"
6398 " -p --poweroff Switch off the machine\n"
6399 " --reboot Reboot the machine\n"
6400 " -f --force Force immediate halt/power-off/reboot\n"
6401 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6402 " -d --no-wtmp Don't write wtmp record\n"
6403 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6404 program_invocation_short_name
,
6405 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6406 arg_action
== ACTION_REBOOT
? "Reboot" :
6407 arg_action
== ACTION_POWEROFF
? "Power off" :
6411 static void shutdown_help(void) {
6412 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6413 "Shut down the system.\n\n"
6414 " --help Show this help\n"
6415 " -H --halt Halt the machine\n"
6416 " -P --poweroff Power-off the machine\n"
6417 " -r --reboot Reboot the machine\n"
6418 " -h Equivalent to --poweroff, overridden by --halt\n"
6419 " -k Don't halt/power-off/reboot, just send warnings\n"
6420 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6421 " -c Cancel a pending shutdown\n",
6422 program_invocation_short_name
);
6425 static void telinit_help(void) {
6426 printf("%s [OPTIONS...] {COMMAND}\n\n"
6427 "Send control commands to the init daemon.\n\n"
6428 " --help Show this help\n"
6429 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6431 " 0 Power-off the machine\n"
6432 " 6 Reboot the machine\n"
6433 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6434 " 1, s, S Enter rescue mode\n"
6435 " q, Q Reload init daemon configuration\n"
6436 " u, U Reexecute init daemon\n",
6437 program_invocation_short_name
);
6440 static void runlevel_help(void) {
6441 printf("%s [OPTIONS...]\n\n"
6442 "Prints the previous and current runlevel of the init system.\n\n"
6443 " --help Show this help\n",
6444 program_invocation_short_name
);
6447 static void help_types(void) {
6451 puts("Available unit types:");
6452 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6453 puts(unit_type_to_string(i
));
6456 static void help_states(void) {
6460 puts("Available unit load states:");
6461 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6462 puts(unit_load_state_to_string(i
));
6465 puts("\nAvailable unit active states:");
6466 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6467 puts(unit_active_state_to_string(i
));
6470 puts("\nAvailable automount unit substates:");
6471 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6472 puts(automount_state_to_string(i
));
6475 puts("\nAvailable busname unit substates:");
6476 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6477 puts(busname_state_to_string(i
));
6480 puts("\nAvailable device unit substates:");
6481 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6482 puts(device_state_to_string(i
));
6485 puts("\nAvailable mount unit substates:");
6486 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6487 puts(mount_state_to_string(i
));
6490 puts("\nAvailable path unit substates:");
6491 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6492 puts(path_state_to_string(i
));
6495 puts("\nAvailable scope unit substates:");
6496 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6497 puts(scope_state_to_string(i
));
6500 puts("\nAvailable service unit substates:");
6501 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6502 puts(service_state_to_string(i
));
6505 puts("\nAvailable slice unit substates:");
6506 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6507 puts(slice_state_to_string(i
));
6510 puts("\nAvailable snapshot unit substates:");
6511 for (i
= 0; i
< _SNAPSHOT_STATE_MAX
; i
++)
6512 puts(snapshot_state_to_string(i
));
6515 puts("\nAvailable socket unit substates:");
6516 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6517 puts(socket_state_to_string(i
));
6520 puts("\nAvailable swap unit substates:");
6521 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6522 puts(swap_state_to_string(i
));
6525 puts("\nAvailable target unit substates:");
6526 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6527 puts(target_state_to_string(i
));
6530 puts("\nAvailable timer unit substates:");
6531 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6532 puts(timer_state_to_string(i
));
6535 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6544 ARG_IGNORE_DEPENDENCIES
,
6556 ARG_NO_ASK_PASSWORD
,
6569 static const struct option options
[] = {
6570 { "help", no_argument
, NULL
, 'h' },
6571 { "version", no_argument
, NULL
, ARG_VERSION
},
6572 { "type", required_argument
, NULL
, 't' },
6573 { "property", required_argument
, NULL
, 'p' },
6574 { "all", no_argument
, NULL
, 'a' },
6575 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6576 { "after", no_argument
, NULL
, ARG_AFTER
},
6577 { "before", no_argument
, NULL
, ARG_BEFORE
},
6578 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6579 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6580 { "full", no_argument
, NULL
, 'l' },
6581 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6582 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6583 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6584 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6585 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6586 { "user", no_argument
, NULL
, ARG_USER
},
6587 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6588 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6589 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6590 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6591 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6592 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6593 { "quiet", no_argument
, NULL
, 'q' },
6594 { "root", required_argument
, NULL
, ARG_ROOT
},
6595 { "force", no_argument
, NULL
, ARG_FORCE
},
6596 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6597 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6598 { "signal", required_argument
, NULL
, 's' },
6599 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6600 { "host", required_argument
, NULL
, 'H' },
6601 { "machine", required_argument
, NULL
, 'M' },
6602 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6603 { "lines", required_argument
, NULL
, 'n' },
6604 { "output", required_argument
, NULL
, 'o' },
6605 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6606 { "state", required_argument
, NULL
, ARG_STATE
},
6607 { "recursive", no_argument
, NULL
, 'r' },
6608 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6609 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6610 { "now", no_argument
, NULL
, ARG_NOW
},
6611 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6620 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6621 arg_ask_password
= true;
6623 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6635 const char *word
, *state
;
6638 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6639 _cleanup_free_
char *type
;
6641 type
= strndup(word
, size
);
6645 if (streq(type
, "help")) {
6650 if (unit_type_from_string(type
) >= 0) {
6651 if (strv_push(&arg_types
, type
))
6657 /* It's much nicer to use --state= for
6658 * load states, but let's support this
6659 * in --types= too for compatibility
6660 * with old versions */
6661 if (unit_load_state_from_string(optarg
) >= 0) {
6662 if (strv_push(&arg_states
, type
) < 0)
6668 log_error("Unknown unit type or load state '%s'.", type
);
6669 log_info("Use -t help to see a list of allowed values.");
6677 /* Make sure that if the empty property list
6678 was specified, we won't show any properties. */
6679 if (isempty(optarg
) && !arg_properties
) {
6680 arg_properties
= new0(char*, 1);
6681 if (!arg_properties
)
6684 const char *word
, *state
;
6687 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6690 prop
= strndup(word
, size
);
6694 if (strv_consume(&arg_properties
, prop
) < 0)
6699 /* If the user asked for a particular
6700 * property, show it to him, even if it is
6712 arg_dependency
= DEPENDENCY_REVERSE
;
6716 arg_dependency
= DEPENDENCY_AFTER
;
6720 arg_dependency
= DEPENDENCY_BEFORE
;
6723 case ARG_SHOW_TYPES
:
6724 arg_show_types
= true;
6728 arg_job_mode
= optarg
;
6732 arg_job_mode
= "fail";
6735 case ARG_IRREVERSIBLE
:
6736 arg_job_mode
= "replace-irreversibly";
6739 case ARG_IGNORE_DEPENDENCIES
:
6740 arg_job_mode
= "ignore-dependencies";
6744 arg_scope
= UNIT_FILE_USER
;
6748 arg_scope
= UNIT_FILE_SYSTEM
;
6752 arg_scope
= UNIT_FILE_GLOBAL
;
6756 arg_no_block
= true;
6760 arg_no_legend
= true;
6764 arg_no_pager
= true;
6780 if (strv_extend(&arg_states
, "failed") < 0)
6798 arg_no_reload
= true;
6802 arg_kill_who
= optarg
;
6806 arg_signal
= signal_from_string_try_harder(optarg
);
6807 if (arg_signal
< 0) {
6808 log_error("Failed to parse signal string %s.", optarg
);
6813 case ARG_NO_ASK_PASSWORD
:
6814 arg_ask_password
= false;
6818 arg_transport
= BUS_TRANSPORT_REMOTE
;
6823 arg_transport
= BUS_TRANSPORT_MACHINE
;
6832 if (safe_atou(optarg
, &arg_lines
) < 0) {
6833 log_error("Failed to parse lines '%s'", optarg
);
6839 arg_output
= output_mode_from_string(optarg
);
6840 if (arg_output
< 0) {
6841 log_error("Unknown output '%s'.", optarg
);
6847 arg_ignore_inhibitors
= true;
6854 case ARG_FIRMWARE_SETUP
:
6855 arg_firmware_setup
= true;
6859 const char *word
, *state
;
6862 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6863 _cleanup_free_
char *s
= NULL
;
6865 s
= strndup(word
, size
);
6869 if (streq(s
, "help")) {
6874 if (strv_consume(&arg_states
, s
) < 0)
6881 if (geteuid() != 0) {
6882 log_error("--recursive requires root privileges.");
6886 arg_recursive
= true;
6889 case ARG_PRESET_MODE
:
6891 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6892 if (arg_preset_mode
< 0) {
6893 log_error("Failed to parse preset mode: %s.", optarg
);
6904 if (strv_extend(&arg_wall
, optarg
) < 0)
6912 assert_not_reached("Unhandled option");
6915 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6916 log_error("Cannot access user instance remotely.");
6923 static int halt_parse_argv(int argc
, char *argv
[]) {
6932 static const struct option options
[] = {
6933 { "help", no_argument
, NULL
, ARG_HELP
},
6934 { "halt", no_argument
, NULL
, ARG_HALT
},
6935 { "poweroff", no_argument
, NULL
, 'p' },
6936 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6937 { "force", no_argument
, NULL
, 'f' },
6938 { "wtmp-only", no_argument
, NULL
, 'w' },
6939 { "no-wtmp", no_argument
, NULL
, 'd' },
6940 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6949 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6950 if (runlevel
== '0' || runlevel
== '6')
6953 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6961 arg_action
= ACTION_HALT
;
6965 if (arg_action
!= ACTION_REBOOT
)
6966 arg_action
= ACTION_POWEROFF
;
6970 arg_action
= ACTION_REBOOT
;
6992 /* Compatibility nops */
6999 assert_not_reached("Unhandled option");
7002 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7003 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7006 } else if (optind
< argc
) {
7007 log_error("Too many arguments.");
7014 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7018 if (streq(t
, "now"))
7020 else if (!strchr(t
, ':')) {
7023 if (safe_atou64(t
, &u
) < 0)
7026 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7035 hour
= strtol(t
, &e
, 10);
7036 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7039 minute
= strtol(e
+1, &e
, 10);
7040 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7043 n
= now(CLOCK_REALTIME
);
7044 s
= (time_t) (n
/ USEC_PER_SEC
);
7046 assert_se(localtime_r(&s
, &tm
));
7048 tm
.tm_hour
= (int) hour
;
7049 tm
.tm_min
= (int) minute
;
7052 assert_se(s
= mktime(&tm
));
7054 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7057 *_u
+= USEC_PER_DAY
;
7063 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7070 static const struct option options
[] = {
7071 { "help", no_argument
, NULL
, ARG_HELP
},
7072 { "halt", no_argument
, NULL
, 'H' },
7073 { "poweroff", no_argument
, NULL
, 'P' },
7074 { "reboot", no_argument
, NULL
, 'r' },
7075 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7076 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7086 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7094 arg_action
= ACTION_HALT
;
7098 arg_action
= ACTION_POWEROFF
;
7103 arg_action
= ACTION_KEXEC
;
7105 arg_action
= ACTION_REBOOT
;
7109 arg_action
= ACTION_KEXEC
;
7113 if (arg_action
!= ACTION_HALT
)
7114 arg_action
= ACTION_POWEROFF
;
7129 /* Compatibility nops */
7133 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7140 assert_not_reached("Unhandled option");
7143 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7144 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7146 log_error("Failed to parse time specification: %s", argv
[optind
]);
7150 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7152 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7153 /* No time argument for shutdown cancel */
7154 wall
= argv
+ optind
;
7155 else if (argc
> optind
+ 1)
7156 /* We skip the time argument */
7157 wall
= argv
+ optind
+ 1;
7160 arg_wall
= strv_copy(wall
);
7170 static int telinit_parse_argv(int argc
, char *argv
[]) {
7177 static const struct option options
[] = {
7178 { "help", no_argument
, NULL
, ARG_HELP
},
7179 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7183 static const struct {
7187 { '0', ACTION_POWEROFF
},
7188 { '6', ACTION_REBOOT
},
7189 { '1', ACTION_RESCUE
},
7190 { '2', ACTION_RUNLEVEL2
},
7191 { '3', ACTION_RUNLEVEL3
},
7192 { '4', ACTION_RUNLEVEL4
},
7193 { '5', ACTION_RUNLEVEL5
},
7194 { 's', ACTION_RESCUE
},
7195 { 'S', ACTION_RESCUE
},
7196 { 'q', ACTION_RELOAD
},
7197 { 'Q', ACTION_RELOAD
},
7198 { 'u', ACTION_REEXEC
},
7199 { 'U', ACTION_REEXEC
}
7208 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7223 assert_not_reached("Unhandled option");
7226 if (optind
>= argc
) {
7227 log_error("%s: required argument missing.", program_invocation_short_name
);
7231 if (optind
+ 1 < argc
) {
7232 log_error("Too many arguments.");
7236 if (strlen(argv
[optind
]) != 1) {
7237 log_error("Expected single character argument.");
7241 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7242 if (table
[i
].from
== argv
[optind
][0])
7245 if (i
>= ELEMENTSOF(table
)) {
7246 log_error("Unknown command '%s'.", argv
[optind
]);
7250 arg_action
= table
[i
].to
;
7257 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7263 static const struct option options
[] = {
7264 { "help", no_argument
, NULL
, ARG_HELP
},
7273 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7284 assert_not_reached("Unhandled option");
7287 if (optind
< argc
) {
7288 log_error("Too many arguments.");
7295 static int parse_argv(int argc
, char *argv
[]) {
7299 if (program_invocation_short_name
) {
7301 if (strstr(program_invocation_short_name
, "halt")) {
7302 arg_action
= ACTION_HALT
;
7303 return halt_parse_argv(argc
, argv
);
7304 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7305 arg_action
= ACTION_POWEROFF
;
7306 return halt_parse_argv(argc
, argv
);
7307 } else if (strstr(program_invocation_short_name
, "reboot")) {
7309 arg_action
= ACTION_KEXEC
;
7311 arg_action
= ACTION_REBOOT
;
7312 return halt_parse_argv(argc
, argv
);
7313 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7314 arg_action
= ACTION_POWEROFF
;
7315 return shutdown_parse_argv(argc
, argv
);
7316 } else if (strstr(program_invocation_short_name
, "init")) {
7318 if (sd_booted() > 0) {
7319 arg_action
= _ACTION_INVALID
;
7320 return telinit_parse_argv(argc
, argv
);
7322 /* Hmm, so some other init system is
7323 * running, we need to forward this
7324 * request to it. For now we simply
7325 * guess that it is Upstart. */
7327 execv(TELINIT
, argv
);
7329 log_error("Couldn't find an alternative telinit implementation to spawn.");
7333 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7334 arg_action
= ACTION_RUNLEVEL
;
7335 return runlevel_parse_argv(argc
, argv
);
7339 arg_action
= ACTION_SYSTEMCTL
;
7340 return systemctl_parse_argv(argc
, argv
);
7343 _pure_
static int action_to_runlevel(void) {
7345 static const char table
[_ACTION_MAX
] = {
7346 [ACTION_HALT
] = '0',
7347 [ACTION_POWEROFF
] = '0',
7348 [ACTION_REBOOT
] = '6',
7349 [ACTION_RUNLEVEL2
] = '2',
7350 [ACTION_RUNLEVEL3
] = '3',
7351 [ACTION_RUNLEVEL4
] = '4',
7352 [ACTION_RUNLEVEL5
] = '5',
7353 [ACTION_RESCUE
] = '1'
7356 assert(arg_action
< _ACTION_MAX
);
7358 return table
[arg_action
];
7361 static int talk_initctl(void) {
7362 #ifdef HAVE_SYSV_COMPAT
7363 struct init_request request
= {
7364 .magic
= INIT_MAGIC
,
7366 .cmd
= INIT_CMD_RUNLVL
7369 _cleanup_close_
int fd
= -1;
7373 rl
= action_to_runlevel();
7377 request
.runlevel
= rl
;
7379 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7381 if (errno
== ENOENT
)
7384 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7387 r
= loop_write(fd
, &request
, sizeof(request
), false);
7389 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7397 static int systemctl_main(int argc
, char *argv
[]) {
7399 static const Verb verbs
[] = {
7400 { "list-units", VERB_ANY
, 1, VERB_DEFAULT
, list_units
},
7401 { "list-unit-files", VERB_ANY
, 1, 0, list_unit_files
},
7402 { "list-sockets", VERB_ANY
, 1, 0, list_sockets
},
7403 { "list-timers", VERB_ANY
, 1, 0, list_timers
},
7404 { "list-jobs", VERB_ANY
, 1, 0, list_jobs
},
7405 { "list-machines", VERB_ANY
, 1, 0, list_machines
},
7406 { "clear-jobs", VERB_ANY
, 1, 0, daemon_reload
},
7407 { "cancel", 2, VERB_ANY
, 0, cancel_job
},
7408 { "start", 2, VERB_ANY
, 0, start_unit
},
7409 { "stop", 2, VERB_ANY
, 0, start_unit
},
7410 { "condstop", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7411 { "reload", 2, VERB_ANY
, 0, start_unit
},
7412 { "restart", 2, VERB_ANY
, 0, start_unit
},
7413 { "try-restart", 2, VERB_ANY
, 0, start_unit
},
7414 { "reload-or-restart", 2, VERB_ANY
, 0, start_unit
},
7415 { "reload-or-try-restart", 2, VERB_ANY
, 0, start_unit
},
7416 { "force-reload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with SysV */
7417 { "condreload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7418 { "condrestart", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with RH */
7419 { "isolate", 2, 2, 0, start_unit
},
7420 { "kill", 2, VERB_ANY
, 0, kill_unit
},
7421 { "is-active", 2, VERB_ANY
, 0, check_unit_active
},
7422 { "check", 2, VERB_ANY
, 0, check_unit_active
},
7423 { "is-failed", 2, VERB_ANY
, 0, check_unit_failed
},
7424 { "show", VERB_ANY
, VERB_ANY
, 0, show
},
7425 { "cat", 2, VERB_ANY
, 0, cat
},
7426 { "status", VERB_ANY
, VERB_ANY
, 0, show
},
7427 { "help", VERB_ANY
, VERB_ANY
, 0, show
},
7428 { "snapshot", VERB_ANY
, 2, 0, snapshot
},
7429 { "delete", 2, VERB_ANY
, 0, delete_snapshot
},
7430 { "daemon-reload", VERB_ANY
, 1, 0, daemon_reload
},
7431 { "daemon-reexec", VERB_ANY
, 1, 0, daemon_reload
},
7432 { "show-environment", VERB_ANY
, 1, 0, show_environment
},
7433 { "set-environment", 2, VERB_ANY
, 0, set_environment
},
7434 { "unset-environment", 2, VERB_ANY
, 0, set_environment
},
7435 { "import-environment", VERB_ANY
, VERB_ANY
, 0, import_environment
},
7436 { "halt", VERB_ANY
, 1, 0, start_special
},
7437 { "poweroff", VERB_ANY
, 1, 0, start_special
},
7438 { "reboot", VERB_ANY
, 2, 0, start_special
},
7439 { "kexec", VERB_ANY
, 1, 0, start_special
},
7440 { "suspend", VERB_ANY
, 1, 0, start_special
},
7441 { "hibernate", VERB_ANY
, 1, 0, start_special
},
7442 { "hybrid-sleep", VERB_ANY
, 1, 0, start_special
},
7443 { "default", VERB_ANY
, 1, 0, start_special
},
7444 { "rescue", VERB_ANY
, 1, 0, start_special
},
7445 { "emergency", VERB_ANY
, 1, 0, start_special
},
7446 { "exit", VERB_ANY
, 2, 0, start_special
},
7447 { "reset-failed", VERB_ANY
, VERB_ANY
, 0, reset_failed
},
7448 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7449 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7450 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7451 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7452 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7453 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7454 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7455 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7456 { "link", 2, VERB_ANY
, 0, enable_unit
},
7457 { "switch-root", 2, VERB_ANY
, 0, switch_root
},
7458 { "list-dependencies", VERB_ANY
, 2, 0, list_dependencies
},
7459 { "set-default", 2, 2, 0, set_default
},
7460 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7461 { "set-property", 3, VERB_ANY
, 0, set_property
},
7462 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7463 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7464 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7465 { "edit", 2, VERB_ANY
, 0, edit
},
7469 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7472 static int reload_with_fallback(void) {
7474 /* First, try systemd via D-Bus. */
7475 if (daemon_reload(0, NULL
, NULL
) >= 0)
7478 /* Nothing else worked, so let's try signals */
7479 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7481 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7482 return log_error_errno(errno
, "kill() failed: %m");
7487 static int start_with_fallback(void) {
7489 /* First, try systemd via D-Bus. */
7490 if (start_unit(0, NULL
, NULL
) >= 0)
7493 /* Nothing else worked, so let's try
7495 if (talk_initctl() > 0)
7498 log_error("Failed to talk to init daemon.");
7502 static int halt_now(enum action a
) {
7504 /* The kernel will automaticall flush ATA disks and suchlike
7505 * on reboot(), but the file systems need to be synce'd
7506 * explicitly in advance. */
7509 /* Make sure C-A-D is handled by the kernel from this point
7511 (void) reboot(RB_ENABLE_CAD
);
7516 log_info("Halting.");
7517 (void) reboot(RB_HALT_SYSTEM
);
7520 case ACTION_POWEROFF
:
7521 log_info("Powering off.");
7522 (void) reboot(RB_POWER_OFF
);
7526 case ACTION_REBOOT
: {
7527 _cleanup_free_
char *param
= NULL
;
7529 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7530 log_info("Rebooting with argument '%s'.", param
);
7531 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7534 log_info("Rebooting.");
7535 (void) reboot(RB_AUTOBOOT
);
7540 assert_not_reached("Unknown action.");
7544 static int logind_schedule_shutdown(void) {
7547 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7548 char date
[FORMAT_TIMESTAMP_MAX
];
7553 (void) logind_set_wall_message();
7555 r
= acquire_bus(BUS_FULL
, &bus
);
7559 switch (arg_action
) {
7563 case ACTION_POWEROFF
:
7564 action
= "poweroff";
7579 action
= strjoina("dry-", action
);
7581 r
= sd_bus_call_method(
7583 "org.freedesktop.login1",
7584 "/org/freedesktop/login1",
7585 "org.freedesktop.login1.Manager",
7593 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7595 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7598 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7603 static int halt_main(void) {
7606 r
= logind_check_inhibitors(arg_action
);
7611 return logind_schedule_shutdown();
7613 if (geteuid() != 0) {
7614 if (arg_dry
|| arg_force
> 0) {
7615 log_error("Must be root.");
7619 /* Try logind if we are a normal user and no special
7620 * mode applies. Maybe PolicyKit allows us to shutdown
7622 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7623 r
= logind_reboot(arg_action
);
7626 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7627 /* requested operation is not
7628 * supported on the local system or
7629 * already in progress */
7631 /* on all other errors, try low-level operation */
7635 if (!arg_dry
&& !arg_force
)
7636 return start_with_fallback();
7638 assert(geteuid() == 0);
7641 if (sd_booted() > 0)
7642 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7644 r
= utmp_put_shutdown();
7646 log_warning_errno(r
, "Failed to write utmp record: %m");
7653 r
= halt_now(arg_action
);
7654 return log_error_errno(r
, "Failed to reboot: %m");
7657 static int runlevel_main(void) {
7658 int r
, runlevel
, previous
;
7660 r
= utmp_get_runlevel(&runlevel
, &previous
);
7667 previous
<= 0 ? 'N' : previous
,
7668 runlevel
<= 0 ? 'N' : runlevel
);
7673 static int logind_cancel_shutdown(void) {
7675 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7679 r
= acquire_bus(BUS_FULL
, &bus
);
7683 (void) logind_set_wall_message();
7685 r
= sd_bus_call_method(
7687 "org.freedesktop.login1",
7688 "/org/freedesktop/login1",
7689 "org.freedesktop.login1.Manager",
7690 "CancelScheduledShutdown",
7694 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7698 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7703 int main(int argc
, char*argv
[]) {
7706 setlocale(LC_ALL
, "");
7707 log_parse_environment();
7710 /* Explicitly not on_tty() to avoid setting cached value.
7711 * This becomes relevant for piping output which might be
7713 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7715 r
= parse_argv(argc
, argv
);
7719 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7720 log_info("Running in chroot, ignoring request.");
7725 /* systemctl_main() will print an error message for the bus
7726 * connection, but only if it needs to */
7728 switch (arg_action
) {
7730 case ACTION_SYSTEMCTL
:
7731 r
= systemctl_main(argc
, argv
);
7735 case ACTION_POWEROFF
:
7741 case ACTION_RUNLEVEL2
:
7742 case ACTION_RUNLEVEL3
:
7743 case ACTION_RUNLEVEL4
:
7744 case ACTION_RUNLEVEL5
:
7746 case ACTION_EMERGENCY
:
7747 case ACTION_DEFAULT
:
7748 r
= start_with_fallback();
7753 r
= reload_with_fallback();
7756 case ACTION_CANCEL_SHUTDOWN
:
7757 r
= logind_cancel_shutdown();
7760 case ACTION_RUNLEVEL
:
7761 r
= runlevel_main();
7764 case _ACTION_INVALID
:
7766 assert_not_reached("Unknown action");
7771 ask_password_agent_close();
7772 polkit_agent_close();
7774 strv_free(arg_types
);
7775 strv_free(arg_states
);
7776 strv_free(arg_properties
);
7778 strv_free(arg_wall
);
7782 return r
< 0 ? EXIT_FAILURE
: r
;