2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Marc-Antoine Perennou
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/reboot.h>
30 #include <sys/reboot.h>
31 #include <sys/socket.h>
35 #include "sd-daemon.h"
38 #include "alloc-util.h"
39 #include "bus-common-errors.h"
40 #include "bus-error.h"
41 #include "bus-message.h"
42 #include "bus-unit-util.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
51 #include "exit-status.h"
54 #include "format-util.h"
56 #include "glob-util.h"
57 #include "hostname-util.h"
62 #include "locale-util.h"
64 #include "logs-show.h"
68 #include "parse-util.h"
69 #include "path-lookup.h"
70 #include "path-util.h"
71 #include "process-util.h"
72 #include "rlimit-util.h"
75 #include "signal-util.h"
76 #include "socket-util.h"
77 #include "spawn-ask-password-agent.h"
78 #include "spawn-polkit-agent.h"
80 #include "stat-util.h"
82 #include "terminal-util.h"
83 #include "unit-name.h"
84 #include "user-util.h"
86 #include "utmp-wtmp.h"
90 /* The init script exit status codes
91 0 program is running or service is OK
92 1 program is dead and /var/run pid file exists
93 2 program is dead and /var/lock lock file exists
94 3 program is not running
95 4 program or service status is unknown
96 5-99 reserved for future LSB use
97 100-149 reserved for distribution use
98 150-199 reserved for application use
102 EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
= 0,
103 EXIT_PROGRAM_DEAD_AND_PID_EXISTS
= 1,
104 EXIT_PROGRAM_DEAD_AND_LOCK_FILE_EXISTS
= 2,
105 EXIT_PROGRAM_NOT_RUNNING
= 3,
106 EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
= 4,
109 static char **arg_types
= NULL
;
110 static char **arg_states
= NULL
;
111 static char **arg_properties
= NULL
;
112 static bool arg_all
= false;
113 static enum dependency
{
119 } arg_dependency
= DEPENDENCY_FORWARD
;
120 static const char *arg_job_mode
= "replace";
121 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
122 static bool arg_wait
= false;
123 static bool arg_no_block
= false;
124 static bool arg_no_legend
= false;
125 static bool arg_no_pager
= false;
126 static bool arg_no_wtmp
= false;
127 static bool arg_no_sync
= false;
128 static bool arg_no_wall
= false;
129 static bool arg_no_reload
= false;
130 static bool arg_value
= false;
131 static bool arg_show_types
= false;
132 static bool arg_ignore_inhibitors
= false;
133 static bool arg_dry
= false;
134 static bool arg_quiet
= false;
135 static bool arg_full
= false;
136 static bool arg_recursive
= false;
137 static int arg_force
= 0;
138 static bool arg_ask_password
= false;
139 static bool arg_runtime
= false;
140 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
141 static char **arg_wall
= NULL
;
142 static const char *arg_kill_who
= NULL
;
143 static int arg_signal
= SIGTERM
;
144 static char *arg_root
= NULL
;
145 static usec_t arg_when
= 0;
146 static char *argv_cmdline
= NULL
;
167 ACTION_CANCEL_SHUTDOWN
,
170 } arg_action
= ACTION_SYSTEMCTL
;
171 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
172 static const char *arg_host
= NULL
;
173 static unsigned arg_lines
= 10;
174 static OutputMode arg_output
= OUTPUT_SHORT
;
175 static bool arg_plain
= false;
176 static bool arg_firmware_setup
= false;
177 static bool arg_now
= false;
178 static bool arg_jobs_before
= false;
179 static bool arg_jobs_after
= false;
181 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
182 static int trivial_method(int argc
, char *argv
[], void *userdata
);
183 static int halt_now(enum action a
);
184 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
186 static bool original_stdout_is_tty
;
188 typedef enum BusFocus
{
189 BUS_FULL
, /* The full bus indicated via --system or --user */
190 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
194 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
196 static UnitFileFlags
args_to_flags(void) {
197 return (arg_runtime
? UNIT_FILE_RUNTIME
: 0) |
198 (arg_force
? UNIT_FILE_FORCE
: 0);
201 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
204 assert(focus
< _BUS_FOCUS_MAX
);
207 /* We only go directly to the manager, if we are using a local transport */
208 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
211 if (getenv_bool("SYSTEMCTL_FORCE_BUS") > 0)
214 if (!busses
[focus
]) {
217 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
219 if (focus
== BUS_MANAGER
)
220 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
222 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
224 return log_error_errno(r
, "Failed to connect to bus: %m");
226 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
229 *ret
= busses
[focus
];
233 static void release_busses(void) {
236 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
237 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
240 static int map_string_no_copy(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
242 const char **p
= userdata
;
245 r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &s
);
255 static void ask_password_agent_open_if_enabled(void) {
257 /* Open the password agent as a child process if necessary */
259 if (!arg_ask_password
)
262 if (arg_scope
!= UNIT_FILE_SYSTEM
)
265 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
268 ask_password_agent_open();
271 static void polkit_agent_open_if_enabled(void) {
273 /* Open the polkit agent as a child process if necessary */
275 if (!arg_ask_password
)
278 if (arg_scope
!= UNIT_FILE_SYSTEM
)
281 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
287 static OutputFlags
get_output_flags(void) {
289 arg_all
* OUTPUT_SHOW_ALL
|
290 arg_full
* OUTPUT_FULL_WIDTH
|
291 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
292 colors_enabled() * OUTPUT_COLOR
|
293 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
296 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
299 if (!sd_bus_error_is_set(error
))
302 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
303 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
304 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
305 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
306 return EXIT_NOPERMISSION
;
308 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
309 return EXIT_NOTINSTALLED
;
311 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
312 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
313 return EXIT_NOTIMPLEMENTED
;
315 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
316 return EXIT_NOTCONFIGURED
;
324 static bool install_client_side(void) {
326 /* Decides when to execute enable/disable/... operations
327 * client-side rather than server-side. */
329 if (running_in_chroot() > 0)
332 if (sd_booted() <= 0)
335 if (!isempty(arg_root
))
338 if (arg_scope
== UNIT_FILE_GLOBAL
)
341 /* Unsupported environment variable, mostly for debugging purposes */
342 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
348 static int compare_unit_info(const void *a
, const void *b
) {
349 const UnitInfo
*u
= a
, *v
= b
;
353 /* First, order by machine */
354 if (!u
->machine
&& v
->machine
)
356 if (u
->machine
&& !v
->machine
)
358 if (u
->machine
&& v
->machine
) {
359 r
= strcasecmp(u
->machine
, v
->machine
);
364 /* Second, order by unit type */
365 d1
= strrchr(u
->id
, '.');
366 d2
= strrchr(v
->id
, '.');
368 r
= strcasecmp(d1
, d2
);
373 /* Third, order by name */
374 return strcasecmp(u
->id
, v
->id
);
377 static const char* unit_type_suffix(const char *name
) {
380 dot
= strrchr(name
, '.');
387 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
390 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
393 if (arg_types
&& !strv_find(arg_types
, unit_type_suffix(u
->id
)))
399 /* Note that '--all' is not purely a state filter, but also a
400 * filter that hides units that "follow" other units (which is
401 * used for device units that appear under different names). */
402 if (!isempty(u
->following
))
405 if (!strv_isempty(arg_states
))
408 /* By default show all units except the ones in inactive
409 * state and with no pending job */
413 if (streq(u
->active_state
, "inactive"))
419 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
420 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
, max_desc_len
;
422 unsigned n_shown
= 0;
425 max_id_len
= strlen("UNIT");
426 load_len
= strlen("LOAD");
427 active_len
= strlen("ACTIVE");
428 sub_len
= strlen("SUB");
429 job_len
= strlen("JOB");
430 max_desc_len
= strlen("DESCRIPTION");
432 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
433 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
434 load_len
= MAX(load_len
, strlen(u
->load_state
));
435 active_len
= MAX(active_len
, strlen(u
->active_state
));
436 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
437 max_desc_len
= MAX(max_desc_len
, strlen(u
->description
));
439 if (u
->job_id
!= 0) {
440 job_len
= MAX(job_len
, strlen(u
->job_type
));
444 if (!arg_no_legend
&&
445 (streq(u
->active_state
, "failed") ||
446 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
450 if (!arg_full
&& original_stdout_is_tty
) {
453 id_len
= MIN(max_id_len
, 25u); /* as much as it needs, but at most 25 for now */
454 basic_len
= circle_len
+ 1 + id_len
+ 1 + load_len
+ 1 + active_len
+ 1 + sub_len
+ 1;
457 basic_len
+= job_len
+ 1;
459 if (basic_len
< (unsigned) columns()) {
460 unsigned extra_len
, incr
;
461 extra_len
= columns() - basic_len
;
463 /* Either UNIT already got 25, or is fully satisfied.
464 * Grant up to 25 to DESC now. */
465 incr
= MIN(extra_len
, 25u);
469 /* Of the remainder give as much as the ID needs to the ID, and give the rest to the
470 * description but not more than it needs. */
472 incr
= MIN(max_id_len
- id_len
, extra_len
);
474 desc_len
+= MIN(extra_len
- incr
, max_desc_len
- desc_len
);
480 desc_len
= max_desc_len
;
483 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
484 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
485 const char *on_underline
= "", *off_underline
= "";
486 const char *on_loaded
= "", *off_loaded
= "";
487 const char *on_active
= "", *off_active
= "";
488 const char *on_circle
= "", *off_circle
= "";
490 bool circle
= false, underline
= false;
492 if (!n_shown
&& !arg_no_legend
) {
497 printf("%s%-*s %-*s %-*s %-*s ",
501 active_len
, "ACTIVE",
505 printf("%-*s ", job_len
, "JOB");
509 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
516 if (u
+ 1 < unit_infos
+ c
&&
517 !streq(unit_type_suffix(u
->id
), unit_type_suffix((u
+ 1)->id
))) {
518 on_underline
= ansi_underline();
519 off_underline
= ansi_normal();
523 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
524 on_circle
= ansi_highlight_yellow();
525 off_circle
= ansi_normal();
527 on_loaded
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
528 off_loaded
= underline
? on_underline
: ansi_normal();
529 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
530 on_circle
= ansi_highlight_red();
531 off_circle
= ansi_normal();
533 on_active
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
534 off_active
= underline
? on_underline
: ansi_normal();
538 j
= strjoin(u
->machine
, ":", u
->id
);
547 e
= ellipsize(id
, id_len
, 33);
555 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
557 printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
559 on_active
, id_len
, id
, off_active
,
560 on_loaded
, load_len
, u
->load_state
, off_loaded
,
561 on_active
, active_len
, u
->active_state
,
562 sub_len
, u
->sub_state
, off_active
,
563 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
567 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
572 if (!arg_no_legend
) {
573 const char *on
, *off
;
577 "LOAD = Reflects whether the unit definition was properly loaded.\n"
578 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
579 "SUB = The low-level unit activation state, values depend on unit type.");
580 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
581 on
= ansi_highlight();
584 on
= ansi_highlight_red();
589 printf("%s%u loaded units listed.%s\n"
590 "To show all installed unit files use 'systemctl list-unit-files'.\n",
593 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
594 "To show all installed unit files use 'systemctl list-unit-files'.\n",
601 static int get_unit_list(
605 UnitInfo
**unit_infos
,
607 sd_bus_message
**_reply
) {
609 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
610 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
611 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
615 bool fallback
= false;
621 r
= sd_bus_message_new_method_call(
624 "org.freedesktop.systemd1",
625 "/org/freedesktop/systemd1",
626 "org.freedesktop.systemd1.Manager",
627 "ListUnitsByPatterns");
629 return bus_log_create_error(r
);
631 r
= sd_bus_message_append_strv(m
, arg_states
);
633 return bus_log_create_error(r
);
635 r
= sd_bus_message_append_strv(m
, patterns
);
637 return bus_log_create_error(r
);
639 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
640 if (r
< 0 && (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
) ||
641 sd_bus_error_has_name(&error
, SD_BUS_ERROR_ACCESS_DENIED
))) {
642 /* Fallback to legacy ListUnitsFiltered method */
644 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
645 m
= sd_bus_message_unref(m
);
646 sd_bus_error_free(&error
);
648 r
= sd_bus_message_new_method_call(
651 "org.freedesktop.systemd1",
652 "/org/freedesktop/systemd1",
653 "org.freedesktop.systemd1.Manager",
654 "ListUnitsFiltered");
656 return bus_log_create_error(r
);
658 r
= sd_bus_message_append_strv(m
, arg_states
);
660 return bus_log_create_error(r
);
662 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
665 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
667 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
669 return bus_log_parse_error(r
);
671 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
674 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
677 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
680 (*unit_infos
)[c
++] = u
;
683 return bus_log_parse_error(r
);
685 r
= sd_bus_message_exit_container(reply
);
687 return bus_log_parse_error(r
);
695 static void message_set_freep(Set
**set
) {
698 while ((m
= set_steal_first(*set
)))
699 sd_bus_message_unref(m
);
704 static int get_unit_list_recursive(
707 UnitInfo
**_unit_infos
,
711 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
712 _cleanup_(message_set_freep
) Set
*replies
;
713 sd_bus_message
*reply
;
721 replies
= set_new(NULL
);
725 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
729 r
= set_put(replies
, reply
);
731 sd_bus_message_unref(reply
);
736 _cleanup_strv_free_
char **machines
= NULL
;
739 r
= sd_get_machine_names(&machines
);
741 return log_error_errno(r
, "Failed to get machine names: %m");
743 STRV_FOREACH(i
, machines
) {
744 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
747 r
= sd_bus_open_system_machine(&container
, *i
);
749 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
753 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
759 r
= set_put(replies
, reply
);
761 sd_bus_message_unref(reply
);
766 *_machines
= machines
;
771 *_unit_infos
= unit_infos
;
780 static int list_units(int argc
, char *argv
[], void *userdata
) {
781 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
782 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
783 _cleanup_strv_free_
char **machines
= NULL
;
787 r
= acquire_bus(BUS_MANAGER
, &bus
);
791 pager_open(arg_no_pager
, false);
793 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
797 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
798 return output_units_list(unit_infos
, r
);
801 static int get_triggered_units(
806 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
813 r
= sd_bus_get_property_strv(
815 "org.freedesktop.systemd1",
817 "org.freedesktop.systemd1.Unit",
822 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
827 static int get_listening(
829 const char* unit_path
,
832 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
833 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
834 const char *type
, *path
;
837 r
= sd_bus_get_property(
839 "org.freedesktop.systemd1",
841 "org.freedesktop.systemd1.Socket",
847 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
849 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
851 return bus_log_parse_error(r
);
853 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
855 r
= strv_extend(listening
, type
);
859 r
= strv_extend(listening
, path
);
866 return bus_log_parse_error(r
);
868 r
= sd_bus_message_exit_container(reply
);
870 return bus_log_parse_error(r
);
882 /* Note: triggered is a list here, although it almost certainly
883 * will always be one unit. Nevertheless, dbus API allows for multiple
884 * values, so let's follow that. */
887 /* The strv above is shared. free is set only in the first one. */
891 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
897 if (!a
->machine
&& b
->machine
)
899 if (a
->machine
&& !b
->machine
)
901 if (a
->machine
&& b
->machine
) {
902 o
= strcasecmp(a
->machine
, b
->machine
);
907 o
= strcmp(a
->path
, b
->path
);
909 o
= strcmp(a
->type
, b
->type
);
914 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
915 struct socket_info
*s
;
916 unsigned pathlen
= strlen("LISTEN"),
917 typelen
= strlen("TYPE") * arg_show_types
,
918 socklen
= strlen("UNIT"),
919 servlen
= strlen("ACTIVATES");
920 const char *on
, *off
;
922 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
926 socklen
= MAX(socklen
, strlen(s
->id
));
928 typelen
= MAX(typelen
, strlen(s
->type
));
929 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
931 STRV_FOREACH(a
, s
->triggered
)
932 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
933 servlen
= MAX(servlen
, tmp
);
938 printf("%-*s %-*.*s%-*s %s\n",
940 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
944 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
945 _cleanup_free_
char *j
= NULL
;
950 j
= strjoin(s
->machine
, ":", s
->path
);
958 printf("%-*s %-*s %-*s",
959 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
962 pathlen
, path
, socklen
, s
->id
);
963 STRV_FOREACH(a
, s
->triggered
)
965 a
== s
->triggered
? "" : ",", *a
);
969 on
= ansi_highlight();
974 on
= ansi_highlight_red();
978 if (!arg_no_legend
) {
979 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
981 printf("Pass --all to see loaded but inactive sockets, too.\n");
987 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
988 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
989 _cleanup_strv_free_
char **machines
= NULL
;
990 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
991 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
993 struct socket_info
*s
;
999 r
= acquire_bus(BUS_MANAGER
, &bus
);
1003 pager_open(arg_no_pager
, false);
1005 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1009 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1010 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
1013 if (!endswith(u
->id
, ".socket"))
1016 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1020 c
= get_listening(bus
, u
->unit_path
, &listening
);
1026 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
1031 for (i
= 0; i
< c
; i
++)
1032 socket_infos
[cs
+ i
] = (struct socket_info
) {
1033 .machine
= u
->machine
,
1035 .type
= listening
[i
*2],
1036 .path
= listening
[i
*2 + 1],
1037 .triggered
= triggered
,
1038 .own_triggered
= i
==0,
1041 /* from this point on we will cleanup those socket_infos */
1044 listening
= triggered
= NULL
; /* avoid cleanup */
1047 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
1048 (__compar_fn_t
) socket_info_compare
);
1050 output_sockets_list(socket_infos
, cs
);
1053 assert(cs
== 0 || socket_infos
);
1054 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
1057 if (s
->own_triggered
)
1058 strv_free(s
->triggered
);
1064 static int get_next_elapse(
1067 dual_timestamp
*next
) {
1069 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1077 r
= sd_bus_get_property_trivial(
1079 "org.freedesktop.systemd1",
1081 "org.freedesktop.systemd1.Timer",
1082 "NextElapseUSecMonotonic",
1087 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1089 r
= sd_bus_get_property_trivial(
1091 "org.freedesktop.systemd1",
1093 "org.freedesktop.systemd1.Timer",
1094 "NextElapseUSecRealtime",
1099 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1105 static int get_last_trigger(
1110 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1117 r
= sd_bus_get_property_trivial(
1119 "org.freedesktop.systemd1",
1121 "org.freedesktop.systemd1.Timer",
1127 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1133 const char* machine
;
1136 usec_t last_trigger
;
1140 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1146 if (!a
->machine
&& b
->machine
)
1148 if (a
->machine
&& !b
->machine
)
1150 if (a
->machine
&& b
->machine
) {
1151 o
= strcasecmp(a
->machine
, b
->machine
);
1156 if (a
->next_elapse
< b
->next_elapse
)
1158 if (a
->next_elapse
> b
->next_elapse
)
1161 return strcmp(a
->id
, b
->id
);
1164 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1165 struct timer_info
*t
;
1167 nextlen
= strlen("NEXT"),
1168 leftlen
= strlen("LEFT"),
1169 lastlen
= strlen("LAST"),
1170 passedlen
= strlen("PASSED"),
1171 unitlen
= strlen("UNIT"),
1172 activatelen
= strlen("ACTIVATES");
1174 const char *on
, *off
;
1176 assert(timer_infos
|| n
== 0);
1178 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1182 if (t
->next_elapse
> 0) {
1183 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1185 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1186 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1188 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1189 leftlen
= MAX(leftlen
, strlen(trel
));
1192 if (t
->last_trigger
> 0) {
1193 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1195 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1196 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1198 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1199 passedlen
= MAX(passedlen
, strlen(trel
));
1202 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1204 STRV_FOREACH(a
, t
->triggered
)
1205 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1207 activatelen
= MAX(activatelen
, ul
);
1212 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1216 passedlen
, "PASSED",
1220 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1221 _cleanup_free_
char *j
= NULL
;
1223 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1224 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1227 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1228 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1230 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1231 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1234 j
= strjoin(t
->machine
, ":", t
->id
);
1241 printf("%-*s %-*s %-*s %-*s %-*s",
1242 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1244 STRV_FOREACH(a
, t
->triggered
)
1246 a
== t
->triggered
? "" : ",", *a
);
1250 on
= ansi_highlight();
1251 off
= ansi_normal();
1255 on
= ansi_highlight_red();
1256 off
= ansi_normal();
1259 if (!arg_no_legend
) {
1260 printf("%s%u timers listed.%s\n", on
, n
, off
);
1262 printf("Pass --all to see loaded but inactive timers, too.\n");
1268 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1274 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1277 if (next
->monotonic
> nw
->monotonic
)
1278 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1280 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1282 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1283 next_elapse
= MIN(converted
, next
->realtime
);
1285 next_elapse
= converted
;
1288 next_elapse
= next
->realtime
;
1293 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1294 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1295 _cleanup_strv_free_
char **machines
= NULL
;
1296 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1297 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1298 struct timer_info
*t
;
1306 r
= acquire_bus(BUS_MANAGER
, &bus
);
1310 pager_open(arg_no_pager
, false);
1312 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1316 dual_timestamp_get(&nw
);
1318 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1319 _cleanup_strv_free_
char **triggered
= NULL
;
1320 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1323 if (!endswith(u
->id
, ".timer"))
1326 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1330 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1334 get_last_trigger(bus
, u
->unit_path
, &last
);
1336 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1341 m
= calc_next_elapse(&nw
, &next
);
1343 timer_infos
[c
++] = (struct timer_info
) {
1344 .machine
= u
->machine
,
1347 .last_trigger
= last
,
1348 .triggered
= triggered
,
1351 triggered
= NULL
; /* avoid cleanup */
1354 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1355 (__compar_fn_t
) timer_info_compare
);
1357 output_timers_list(timer_infos
, c
);
1360 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1361 strv_free(t
->triggered
);
1366 static int compare_unit_file_list(const void *a
, const void *b
) {
1367 const char *d1
, *d2
;
1368 const UnitFileList
*u
= a
, *v
= b
;
1370 d1
= strrchr(u
->path
, '.');
1371 d2
= strrchr(v
->path
, '.');
1376 r
= strcasecmp(d1
, d2
);
1381 return strcasecmp(basename(u
->path
), basename(v
->path
));
1384 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1387 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1390 if (!strv_isempty(arg_types
)) {
1393 dot
= strrchr(u
->path
, '.');
1397 if (!strv_find(arg_types
, dot
+1))
1401 if (!strv_isempty(states
) &&
1402 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1408 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1409 unsigned max_id_len
, id_cols
, state_cols
;
1410 const UnitFileList
*u
;
1412 max_id_len
= strlen("UNIT FILE");
1413 state_cols
= strlen("STATE");
1415 for (u
= units
; u
< units
+ c
; u
++) {
1416 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1417 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1421 unsigned basic_cols
;
1423 id_cols
= MIN(max_id_len
, 25u);
1424 basic_cols
= 1 + id_cols
+ state_cols
;
1425 if (basic_cols
< (unsigned) columns())
1426 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1428 id_cols
= max_id_len
;
1430 if (!arg_no_legend
&& c
> 0)
1431 printf("%s%-*s %-*s%s\n",
1433 id_cols
, "UNIT FILE",
1434 state_cols
, "STATE",
1437 for (u
= units
; u
< units
+ c
; u
++) {
1438 const char *on_underline
= NULL
, *on_color
= NULL
, *off
= NULL
, *id
;
1439 _cleanup_free_
char *e
= NULL
;
1442 underline
= u
+ 1 < units
+ c
&&
1443 !streq(unit_type_suffix(u
->path
), unit_type_suffix((u
+ 1)->path
));
1446 on_underline
= ansi_underline();
1448 if (IN_SET(u
->state
,
1450 UNIT_FILE_MASKED_RUNTIME
,
1453 on_color
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
1454 else if (u
->state
== UNIT_FILE_ENABLED
)
1455 on_color
= underline
? ansi_highlight_green_underline() : ansi_highlight_green();
1457 if (on_underline
|| on_color
)
1458 off
= ansi_normal();
1460 id
= basename(u
->path
);
1462 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1464 printf("%s%-*s %s%-*s%s\n",
1465 strempty(on_underline
),
1466 id_cols
, e
? e
: id
,
1467 strempty(on_color
), state_cols
, unit_file_state_to_string(u
->state
), strempty(off
));
1471 printf("\n%u unit files listed.\n", c
);
1474 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1475 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1476 _cleanup_free_ UnitFileList
*units
= NULL
;
1483 bool fallback
= false;
1485 if (install_client_side()) {
1491 h
= hashmap_new(&string_hash_ops
);
1495 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1497 unit_file_list_free(h
);
1498 return log_error_errno(r
, "Failed to get unit file list: %m");
1501 n_units
= hashmap_size(h
);
1503 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1505 unit_file_list_free(h
);
1509 HASHMAP_FOREACH(u
, h
, i
) {
1510 if (!output_show_unit_file(u
, NULL
, NULL
))
1517 assert(c
<= n_units
);
1522 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1523 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1526 r
= acquire_bus(BUS_MANAGER
, &bus
);
1530 r
= sd_bus_message_new_method_call(
1533 "org.freedesktop.systemd1",
1534 "/org/freedesktop/systemd1",
1535 "org.freedesktop.systemd1.Manager",
1536 "ListUnitFilesByPatterns");
1538 return bus_log_create_error(r
);
1540 r
= sd_bus_message_append_strv(m
, arg_states
);
1542 return bus_log_create_error(r
);
1544 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1546 return bus_log_create_error(r
);
1548 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1549 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1550 /* Fallback to legacy ListUnitFiles method */
1552 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1553 m
= sd_bus_message_unref(m
);
1554 sd_bus_error_free(&error
);
1556 r
= sd_bus_message_new_method_call(
1559 "org.freedesktop.systemd1",
1560 "/org/freedesktop/systemd1",
1561 "org.freedesktop.systemd1.Manager",
1564 return bus_log_create_error(r
);
1566 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1569 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1571 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1573 return bus_log_parse_error(r
);
1575 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1577 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1580 units
[c
] = (struct UnitFileList
) {
1582 unit_file_state_from_string(state
)
1585 if (output_show_unit_file(&units
[c
],
1586 fallback
? arg_states
: NULL
,
1587 fallback
? strv_skip(argv
, 1) : NULL
))
1592 return bus_log_parse_error(r
);
1594 r
= sd_bus_message_exit_container(reply
);
1596 return bus_log_parse_error(r
);
1599 pager_open(arg_no_pager
, false);
1601 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1602 output_unit_file_list(units
, c
);
1604 if (install_client_side())
1605 for (unit
= units
; unit
< units
+ c
; unit
++)
1611 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1612 _cleanup_free_
char *n
= NULL
;
1613 size_t max_len
= MAX(columns(),20u);
1619 for (i
= level
- 1; i
>= 0; i
--) {
1621 if (len
> max_len
- 3 && !arg_full
) {
1622 printf("%s...\n",max_len
% 2 ? "" : " ");
1625 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1629 if (len
> max_len
- 3 && !arg_full
) {
1630 printf("%s...\n",max_len
% 2 ? "" : " ");
1634 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1638 printf("%s\n", name
);
1642 n
= ellipsize(name
, max_len
-len
, 100);
1650 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1652 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1653 [DEPENDENCY_FORWARD
] = "Requires\0"
1658 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1663 [DEPENDENCY_AFTER
] = "After\0",
1664 [DEPENDENCY_BEFORE
] = "Before\0",
1667 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1668 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1669 _cleanup_strv_free_
char **ret
= NULL
;
1670 _cleanup_free_
char *path
= NULL
;
1676 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1678 path
= unit_dbus_path_from_name(name
);
1682 r
= sd_bus_call_method(
1684 "org.freedesktop.systemd1",
1686 "org.freedesktop.DBus.Properties",
1690 "s", "org.freedesktop.systemd1.Unit");
1692 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1694 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1696 return bus_log_parse_error(r
);
1698 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1701 r
= sd_bus_message_read(reply
, "s", &prop
);
1703 return bus_log_parse_error(r
);
1705 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1706 r
= sd_bus_message_skip(reply
, "v");
1708 return bus_log_parse_error(r
);
1711 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1713 return bus_log_parse_error(r
);
1715 r
= bus_message_read_strv_extend(reply
, &ret
);
1717 return bus_log_parse_error(r
);
1719 r
= sd_bus_message_exit_container(reply
);
1721 return bus_log_parse_error(r
);
1724 r
= sd_bus_message_exit_container(reply
);
1726 return bus_log_parse_error(r
);
1730 return bus_log_parse_error(r
);
1732 r
= sd_bus_message_exit_container(reply
);
1734 return bus_log_parse_error(r
);
1736 *deps
= strv_uniq(ret
);
1742 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1743 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1745 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1747 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1750 return strcasecmp(*a
, *b
);
1753 static int list_dependencies_one(
1758 unsigned int branches
) {
1760 _cleanup_strv_free_
char **deps
= NULL
;
1768 r
= strv_extend(units
, name
);
1772 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1776 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1778 STRV_FOREACH(c
, deps
) {
1779 if (strv_contains(*units
, *c
)) {
1782 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1792 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1795 (void) get_state_one_unit(bus
, *c
, &active_state
);
1797 switch (active_state
) {
1799 case UNIT_RELOADING
:
1800 case UNIT_ACTIVATING
:
1801 on
= ansi_highlight_green();
1805 case UNIT_DEACTIVATING
:
1810 on
= ansi_highlight_red();
1814 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1817 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1821 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1822 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1829 strv_remove(*units
, name
);
1834 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1835 _cleanup_strv_free_
char **units
= NULL
;
1836 _cleanup_free_
char *unit
= NULL
;
1842 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1844 return log_error_errno(r
, "Failed to mangle unit name: %m");
1848 u
= SPECIAL_DEFAULT_TARGET
;
1850 r
= acquire_bus(BUS_MANAGER
, &bus
);
1854 pager_open(arg_no_pager
, false);
1858 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1861 struct machine_info
{
1865 char *control_group
;
1866 uint32_t n_failed_units
;
1871 static const struct bus_properties_map machine_info_property_map
[] = {
1872 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1873 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1874 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1875 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1876 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1880 static void machine_info_clear(struct machine_info
*info
) {
1885 free(info
->control_group
);
1889 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1895 for (i
= 0; i
< n
; i
++)
1896 machine_info_clear(&machine_infos
[i
]);
1898 free(machine_infos
);
1901 static int compare_machine_info(const void *a
, const void *b
) {
1902 const struct machine_info
*u
= a
, *v
= b
;
1904 if (u
->is_host
!= v
->is_host
)
1905 return u
->is_host
> v
->is_host
? -1 : 1;
1907 return strcasecmp(u
->name
, v
->name
);
1910 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1911 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1917 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1924 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, NULL
, mi
);
1931 static bool output_show_machine(const char *name
, char **patterns
) {
1932 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1935 static int get_machine_list(
1937 struct machine_info
**_machine_infos
,
1940 struct machine_info
*machine_infos
= NULL
;
1941 _cleanup_strv_free_
char **m
= NULL
;
1942 _cleanup_free_
char *hn
= NULL
;
1947 hn
= gethostname_malloc();
1951 if (output_show_machine(hn
, patterns
)) {
1952 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1955 machine_infos
[c
].is_host
= true;
1956 machine_infos
[c
].name
= hn
;
1959 (void) get_machine_properties(bus
, &machine_infos
[c
]);
1963 r
= sd_get_machine_names(&m
);
1965 return log_error_errno(r
, "Failed to get machine list: %m");
1967 STRV_FOREACH(i
, m
) {
1968 _cleanup_free_
char *class = NULL
;
1970 if (!output_show_machine(*i
, patterns
))
1973 sd_machine_get_class(*i
, &class);
1974 if (!streq_ptr(class, "container"))
1977 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1978 free_machines_list(machine_infos
, c
);
1982 machine_infos
[c
].is_host
= false;
1983 machine_infos
[c
].name
= strdup(*i
);
1984 if (!machine_infos
[c
].name
) {
1985 free_machines_list(machine_infos
, c
);
1989 (void) get_machine_properties(NULL
, &machine_infos
[c
]);
1993 *_machine_infos
= machine_infos
;
1997 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1998 struct machine_info
*m
;
2001 namelen
= sizeof("NAME") - 1,
2002 statelen
= sizeof("STATE") - 1,
2003 failedlen
= sizeof("FAILED") - 1,
2004 jobslen
= sizeof("JOBS") - 1;
2006 assert(machine_infos
|| n
== 0);
2008 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2009 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
2010 statelen
= MAX(statelen
, strlen_ptr(m
->state
));
2011 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
2012 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
2014 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
2018 if (!arg_no_legend
) {
2022 printf("%-*s %-*s %-*s %-*s\n",
2025 failedlen
, "FAILED",
2029 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2030 const char *on_state
= "", *off_state
= "";
2031 const char *on_failed
= "", *off_failed
= "";
2032 bool circle
= false;
2034 if (streq_ptr(m
->state
, "degraded")) {
2035 on_state
= ansi_highlight_red();
2036 off_state
= ansi_normal();
2038 } else if (!streq_ptr(m
->state
, "running")) {
2039 on_state
= ansi_highlight_yellow();
2040 off_state
= ansi_normal();
2044 if (m
->n_failed_units
> 0) {
2045 on_failed
= ansi_highlight_red();
2046 off_failed
= ansi_normal();
2048 on_failed
= off_failed
= "";
2051 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
2054 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2055 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
2056 on_state
, statelen
, strna(m
->state
), off_state
,
2057 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2058 jobslen
, m
->n_jobs
);
2060 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2061 namelen
, strna(m
->name
),
2062 on_state
, statelen
, strna(m
->state
), off_state
,
2063 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2064 jobslen
, m
->n_jobs
);
2068 printf("\n%u machines listed.\n", n
);
2071 static int list_machines(int argc
, char *argv
[], void *userdata
) {
2072 struct machine_info
*machine_infos
= NULL
;
2076 if (geteuid() != 0) {
2077 log_error("Must be root.");
2081 r
= acquire_bus(BUS_MANAGER
, &bus
);
2085 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2089 pager_open(arg_no_pager
, false);
2091 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2092 output_machines_list(machine_infos
, r
);
2093 free_machines_list(machine_infos
, r
);
2098 static int get_default(int argc
, char *argv
[], void *userdata
) {
2099 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2100 _cleanup_free_
char *_path
= NULL
;
2104 if (install_client_side()) {
2105 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2107 return log_error_errno(r
, "Failed to get default target: %m");
2112 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2115 r
= acquire_bus(BUS_MANAGER
, &bus
);
2119 r
= sd_bus_call_method(
2121 "org.freedesktop.systemd1",
2122 "/org/freedesktop/systemd1",
2123 "org.freedesktop.systemd1.Manager",
2129 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2131 r
= sd_bus_message_read(reply
, "s", &path
);
2133 return bus_log_parse_error(r
);
2137 printf("%s\n", path
);
2142 static int set_default(int argc
, char *argv
[], void *userdata
) {
2143 _cleanup_free_
char *unit
= NULL
;
2144 UnitFileChange
*changes
= NULL
;
2145 unsigned n_changes
= 0;
2151 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2153 return log_error_errno(r
, "Failed to mangle unit name: %m");
2155 if (install_client_side()) {
2156 r
= unit_file_set_default(arg_scope
, UNIT_FILE_FORCE
, arg_root
, unit
, &changes
, &n_changes
);
2157 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2162 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2163 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2166 polkit_agent_open_if_enabled();
2168 r
= acquire_bus(BUS_MANAGER
, &bus
);
2172 r
= sd_bus_call_method(
2174 "org.freedesktop.systemd1",
2175 "/org/freedesktop/systemd1",
2176 "org.freedesktop.systemd1.Manager",
2182 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2184 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2188 /* Try to reload if enabled */
2190 r
= daemon_reload(argc
, argv
, userdata
);
2196 unit_file_changes_free(changes
, n_changes
);
2201 static int output_waiting_jobs(sd_bus
*bus
, uint32_t id
, const char *method
, const char *prefix
) {
2202 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2203 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2204 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2210 r
= sd_bus_call_method(
2212 "org.freedesktop.systemd1",
2213 "/org/freedesktop/systemd1",
2214 "org.freedesktop.systemd1.Manager",
2220 return log_debug_errno(r
, "Failed to get waiting jobs for job %" PRIu32
, id
);
2222 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2224 return bus_log_parse_error(r
);
2226 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &other_id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0)
2227 printf("%s %u (%s/%s)\n", prefix
, other_id
, name
, type
);
2229 return bus_log_parse_error(r
);
2231 r
= sd_bus_message_exit_container(reply
);
2233 return bus_log_parse_error(r
);
2240 const char *name
, *type
, *state
;
2243 static void output_jobs_list(sd_bus
*bus
, const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2244 unsigned id_len
, unit_len
, type_len
, state_len
;
2245 const struct job_info
*j
;
2246 const char *on
, *off
;
2247 bool shorten
= false;
2249 assert(n
== 0 || jobs
);
2252 if (!arg_no_legend
) {
2253 on
= ansi_highlight_green();
2254 off
= ansi_normal();
2256 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2261 pager_open(arg_no_pager
, false);
2263 id_len
= strlen("JOB");
2264 unit_len
= strlen("UNIT");
2265 type_len
= strlen("TYPE");
2266 state_len
= strlen("STATE");
2268 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2269 uint32_t id
= j
->id
;
2270 assert(j
->name
&& j
->type
&& j
->state
);
2272 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2273 unit_len
= MAX(unit_len
, strlen(j
->name
));
2274 type_len
= MAX(type_len
, strlen(j
->type
));
2275 state_len
= MAX(state_len
, strlen(j
->state
));
2278 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2279 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2284 printf("%*s %-*s %-*s %-*s\n",
2288 state_len
, "STATE");
2290 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2291 _cleanup_free_
char *e
= NULL
;
2293 if (streq(j
->state
, "running")) {
2294 on
= ansi_highlight();
2295 off
= ansi_normal();
2299 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2300 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2302 on
, unit_len
, e
? e
: j
->name
, off
,
2304 on
, state_len
, j
->state
, off
);
2307 output_waiting_jobs(bus
, j
->id
, "GetJobAfter", "\twaiting for job");
2308 if (arg_jobs_before
)
2309 output_waiting_jobs(bus
, j
->id
, "GetJobBefore", "\tblocking job");
2312 if (!arg_no_legend
) {
2313 on
= ansi_highlight();
2314 off
= ansi_normal();
2316 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2320 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2321 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2324 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2325 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2326 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2327 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2328 _cleanup_free_
struct job_info
*jobs
= NULL
;
2334 bool skipped
= false;
2336 r
= acquire_bus(BUS_MANAGER
, &bus
);
2340 r
= sd_bus_call_method(
2342 "org.freedesktop.systemd1",
2343 "/org/freedesktop/systemd1",
2344 "org.freedesktop.systemd1.Manager",
2350 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2352 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2354 return bus_log_parse_error(r
);
2356 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2357 struct job_info job
= { id
, name
, type
, state
};
2359 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2364 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2370 return bus_log_parse_error(r
);
2372 r
= sd_bus_message_exit_container(reply
);
2374 return bus_log_parse_error(r
);
2376 pager_open(arg_no_pager
, false);
2378 output_jobs_list(bus
, jobs
, c
, skipped
);
2382 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2388 return trivial_method(argc
, argv
, userdata
);
2390 r
= acquire_bus(BUS_MANAGER
, &bus
);
2394 polkit_agent_open_if_enabled();
2396 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2397 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2401 q
= safe_atou32(*name
, &id
);
2403 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2405 q
= sd_bus_call_method(
2407 "org.freedesktop.systemd1",
2408 "/org/freedesktop/systemd1",
2409 "org.freedesktop.systemd1.Manager",
2415 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2424 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2425 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2429 /* We ignore all errors here, since this is used to show a
2432 /* We don't use unit_dbus_path_from_name() directly since we
2433 * don't want to load the unit if it isn't loaded. */
2435 r
= sd_bus_call_method(
2437 "org.freedesktop.systemd1",
2438 "/org/freedesktop/systemd1",
2439 "org.freedesktop.systemd1.Manager",
2447 r
= sd_bus_message_read(reply
, "o", &path
);
2451 r
= sd_bus_get_property_trivial(
2453 "org.freedesktop.systemd1",
2455 "org.freedesktop.systemd1.Unit",
2465 static void warn_unit_file_changed(const char *name
) {
2468 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2469 ansi_highlight_red(),
2472 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2475 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2481 STRV_FOREACH(p
, lp
->search_path
) {
2482 _cleanup_free_
char *path
= NULL
, *lpath
= NULL
;
2485 path
= path_join(NULL
, *p
, unit_name
);
2489 r
= chase_symlinks(path
, arg_root
, 0, &lpath
);
2495 return log_error_errno(r
, "Failed to access path '%s': %m", path
);
2507 static int unit_find_template_path(
2508 const char *unit_name
,
2510 char **fragment_path
,
2513 _cleanup_free_
char *_template
= NULL
;
2516 /* Returns 1 if a fragment was found, 0 if not found, negative on error. */
2518 r
= unit_file_find_path(lp
, unit_name
, fragment_path
);
2520 return r
; /* error or found a real unit */
2522 r
= unit_name_template(unit_name
, &_template
);
2524 return 0; /* not a template, does not exist */
2526 return log_error_errno(r
, "Failed to determine template name: %m");
2528 r
= unit_file_find_path(lp
, _template
, fragment_path
);
2533 *template = _template
;
2539 static int unit_find_paths(
2541 const char *unit_name
,
2543 char **fragment_path
,
2544 char ***dropin_paths
) {
2546 _cleanup_free_
char *path
= NULL
;
2547 _cleanup_strv_free_
char **dropins
= NULL
;
2551 * Finds where the unit is defined on disk. Returns 0 if the unit
2552 * is not found. Returns 1 if it is found, and sets
2553 * - the path to the unit in *path, if it exists on disk,
2554 * - and a strv of existing drop-ins in *dropins,
2555 * if the arg is not NULL and any dropins were found.
2559 assert(fragment_path
);
2562 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2563 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2564 _cleanup_free_
char *unit
= NULL
;
2566 unit
= unit_dbus_path_from_name(unit_name
);
2570 r
= sd_bus_get_property_string(
2572 "org.freedesktop.systemd1",
2574 "org.freedesktop.systemd1.Unit",
2579 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2582 r
= sd_bus_get_property_strv(
2584 "org.freedesktop.systemd1",
2586 "org.freedesktop.systemd1.Unit",
2591 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2594 _cleanup_set_free_ Set
*names
= NULL
;
2595 _cleanup_free_
char *template = NULL
;
2597 names
= set_new(NULL
);
2601 r
= unit_find_template_path(unit_name
, lp
, &path
, &template);
2606 /* We found the unit file. If we followed symlinks, this name might be
2607 * different then the unit_name with started with. Look for dropins matching
2608 * that "final" name. */
2609 r
= set_put(names
, basename(path
));
2611 /* No unit file, let's look for dropins matching the original name.
2612 * systemd has fairly complicated rules (based on unit type and provenience),
2613 * which units are allowed not to have the main unit file. We err on the
2614 * side of including too many files, and always try to load dropins. */
2615 r
= set_put(names
, unit_name
);
2617 /* The cases where we allow a unit to exist without the main file are
2618 * never valid for templates. Don't try to load dropins in this case. */
2622 return log_error_errno(r
, "Failed to add unit name: %m");
2625 r
= unit_file_find_dropin_conf_paths(arg_root
, lp
->search_path
,
2626 NULL
, names
, &dropins
);
2634 if (!isempty(path
)) {
2635 *fragment_path
= path
;
2640 if (dropin_paths
&& !strv_isempty(dropins
)) {
2641 *dropin_paths
= dropins
;
2646 if (r
== 0 && !arg_force
)
2647 log_error("No files found for %s.", unit_name
);
2652 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2653 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2654 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2655 _cleanup_free_
char *buf
= NULL
;
2656 UnitActiveState state
;
2661 assert(active_state
);
2663 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2665 r
= sd_bus_call_method(
2667 "org.freedesktop.systemd1",
2668 "/org/freedesktop/systemd1",
2669 "org.freedesktop.systemd1.Manager",
2675 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2676 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2678 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2679 * considered inactive. */
2680 state
= UNIT_INACTIVE
;
2683 r
= sd_bus_message_read(reply
, "o", &path
);
2685 return bus_log_parse_error(r
);
2687 r
= sd_bus_get_property_string(
2689 "org.freedesktop.systemd1",
2691 "org.freedesktop.systemd1.Unit",
2696 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2698 state
= unit_active_state_from_string(buf
);
2699 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2700 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2705 *active_state
= state
;
2709 static int check_triggering_units(
2713 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2714 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2715 _cleanup_strv_free_
char **triggered_by
= NULL
;
2716 bool print_warning_label
= true;
2717 UnitActiveState active_state
;
2721 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2723 return log_error_errno(r
, "Failed to mangle unit name: %m");
2725 path
= unit_dbus_path_from_name(n
);
2729 r
= sd_bus_get_property_string(
2731 "org.freedesktop.systemd1",
2733 "org.freedesktop.systemd1.Unit",
2738 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2740 if (streq(load_state
, "masked"))
2743 r
= sd_bus_get_property_strv(
2745 "org.freedesktop.systemd1",
2747 "org.freedesktop.systemd1.Unit",
2752 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2754 STRV_FOREACH(i
, triggered_by
) {
2755 r
= get_state_one_unit(bus
, *i
, &active_state
);
2759 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2762 if (print_warning_label
) {
2763 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2764 print_warning_label
= false;
2767 log_warning(" %s", *i
);
2773 static const struct {
2776 } unit_actions
[] = {
2777 { "start", "StartUnit" },
2778 { "stop", "StopUnit" },
2779 { "condstop", "StopUnit" },
2780 { "reload", "ReloadUnit" },
2781 { "restart", "RestartUnit" },
2782 { "try-restart", "TryRestartUnit" },
2783 { "condrestart", "TryRestartUnit" },
2784 { "reload-or-restart", "ReloadOrRestartUnit" },
2785 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2786 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2787 { "condreload", "ReloadOrTryRestartUnit" },
2788 { "force-reload", "ReloadOrTryRestartUnit" }
2791 static const char *verb_to_method(const char *verb
) {
2794 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2795 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2796 return unit_actions
[i
].method
;
2801 static const char *method_to_verb(const char *method
) {
2804 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2805 if (streq_ptr(unit_actions
[i
].method
, method
))
2806 return unit_actions
[i
].verb
;
2818 static void wait_context_free(WaitContext
*c
) {
2819 c
->match
= sd_bus_slot_unref(c
->match
);
2820 c
->event
= sd_event_unref(c
->event
);
2821 c
->unit_paths
= set_free_free(c
->unit_paths
);
2824 static int on_properties_changed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
2825 WaitContext
*c
= userdata
;
2829 path
= sd_bus_message_get_path(m
);
2830 if (!set_contains(c
->unit_paths
, path
))
2833 /* Check if ActiveState changed to inactive/failed */
2834 /* (s interface, a{sv} changed_properties, as invalidated_properties) */
2835 r
= sd_bus_message_skip(m
, "s");
2837 return bus_log_parse_error(r
);
2839 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
2841 return bus_log_parse_error(r
);
2843 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
2846 r
= sd_bus_message_read(m
, "s", &s
);
2848 return bus_log_parse_error(r
);
2850 if (streq(s
, "ActiveState")) {
2853 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, "s");
2855 return bus_log_parse_error(r
);
2857 r
= sd_bus_message_read(m
, "s", &s
);
2859 return bus_log_parse_error(r
);
2861 is_failed
= streq(s
, "failed");
2862 if (streq(s
, "inactive") || is_failed
) {
2863 log_debug("%s became %s, dropping from --wait tracking", path
, s
);
2864 free(set_remove(c
->unit_paths
, path
));
2865 c
->any_failed
= c
->any_failed
|| is_failed
;
2867 log_debug("ActiveState on %s changed to %s", path
, s
);
2869 break; /* no need to dissect the rest of the message */
2871 /* other property */
2872 r
= sd_bus_message_skip(m
, "v");
2874 return bus_log_parse_error(r
);
2876 r
= sd_bus_message_exit_container(m
);
2878 return bus_log_parse_error(r
);
2881 return bus_log_parse_error(r
);
2883 if (set_isempty(c
->unit_paths
))
2884 sd_event_exit(c
->event
, EXIT_SUCCESS
);
2889 static int start_unit_one(
2894 sd_bus_error
*error
,
2896 WaitContext
*wait_context
) {
2898 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2908 _cleanup_free_
char *unit_path
= NULL
;
2911 log_debug("Watching for property changes of %s", name
);
2912 r
= sd_bus_call_method(
2914 "org.freedesktop.systemd1",
2915 "/org/freedesktop/systemd1",
2916 "org.freedesktop.systemd1.Manager",
2922 return log_error_errno(r
, "Failed to RefUnit %s: %s", name
, bus_error_message(error
, r
));
2924 unit_path
= unit_dbus_path_from_name(name
);
2928 r
= set_put_strdup(wait_context
->unit_paths
, unit_path
);
2930 return log_error_errno(r
, "Failed to add unit path %s to set: %m", unit_path
);
2932 mt
= strjoina("type='signal',"
2933 "interface='org.freedesktop.DBus.Properties',"
2934 "path='", unit_path
, "',"
2935 "member='PropertiesChanged'");
2936 r
= sd_bus_add_match(bus
, &wait_context
->match
, mt
, on_properties_changed
, wait_context
);
2938 return log_error_errno(r
, "Failed to add match for PropertiesChanged signal: %m");
2941 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2943 r
= sd_bus_call_method(
2945 "org.freedesktop.systemd1",
2946 "/org/freedesktop/systemd1",
2947 "org.freedesktop.systemd1.Manager",
2955 /* There's always a fallback possible for legacy actions. */
2956 if (arg_action
!= ACTION_SYSTEMCTL
)
2959 verb
= method_to_verb(method
);
2961 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2963 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2964 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2965 log_error("See %s logs and 'systemctl%s status%s %s' for details.",
2966 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2967 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2968 name
[0] == '-' ? " --" : "",
2974 r
= sd_bus_message_read(reply
, "o", &path
);
2976 return bus_log_parse_error(r
);
2978 if (need_daemon_reload(bus
, name
) > 0)
2979 warn_unit_file_changed(name
);
2982 log_debug("Adding %s to the set", path
);
2983 r
= bus_wait_for_jobs_add(w
, path
);
2991 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2992 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2999 STRV_FOREACH(name
, names
) {
3003 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
3005 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
3007 return log_error_errno(r
, "Failed to mangle name: %m");
3009 if (string_is_glob(t
))
3010 r
= strv_consume(&globs
, t
);
3012 r
= strv_consume(&mangled
, t
);
3017 /* Query the manager only if any of the names are a glob, since
3018 * this is fairly expensive */
3019 if (!strv_isempty(globs
)) {
3020 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3021 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
3022 size_t allocated
, n
;
3024 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
3028 n
= strv_length(mangled
);
3031 for (i
= 0; i
< r
; i
++) {
3032 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
3035 mangled
[n
] = strdup(unit_infos
[i
].id
);
3039 mangled
[++n
] = NULL
;
3044 mangled
= NULL
; /* do not free */
3049 static const struct {
3053 } action_table
[_ACTION_MAX
] = {
3054 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
3055 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
3056 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
3057 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
3058 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3059 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3060 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3061 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
3062 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
3063 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
3064 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
3065 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
3066 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
3067 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
3068 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
3071 static enum action
verb_to_action(const char *verb
) {
3074 for (i
= 0; i
< _ACTION_MAX
; i
++)
3075 if (streq_ptr(action_table
[i
].verb
, verb
))
3078 return _ACTION_INVALID
;
3081 static int start_unit(int argc
, char *argv
[], void *userdata
) {
3082 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
3083 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
3084 _cleanup_strv_free_
char **names
= NULL
;
3086 _cleanup_(wait_context_free
) WaitContext wait_context
= {};
3090 if (arg_wait
&& !STR_IN_SET(argv
[0], "start", "restart")) {
3091 log_error("--wait may only be used with the 'start' or 'restart' commands.");
3095 /* we cannot do sender tracking on the private bus, so we need the full
3096 * one for RefUnit to implement --wait */
3097 r
= acquire_bus(arg_wait
? BUS_FULL
: BUS_MANAGER
, &bus
);
3101 ask_password_agent_open_if_enabled();
3102 polkit_agent_open_if_enabled();
3104 if (arg_action
== ACTION_SYSTEMCTL
) {
3107 action
= verb_to_action(argv
[0]);
3109 if (action
!= _ACTION_INVALID
) {
3110 method
= "StartUnit";
3111 mode
= action_table
[action
].mode
;
3112 one_name
= action_table
[action
].target
;
3114 if (streq(argv
[0], "isolate")) {
3115 method
= "StartUnit";
3120 method
= verb_to_method(argv
[0]);
3121 mode
= arg_job_mode
;
3126 assert(arg_action
>= 0 && arg_action
< _ACTION_MAX
);
3127 assert(action_table
[arg_action
].target
);
3128 assert(action_table
[arg_action
].mode
);
3130 method
= "StartUnit";
3131 mode
= action_table
[arg_action
].mode
;
3132 one_name
= action_table
[arg_action
].target
;
3136 names
= strv_new(one_name
, NULL
);
3138 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
3140 return log_error_errno(r
, "Failed to expand names: %m");
3143 if (!arg_no_block
) {
3144 r
= bus_wait_for_jobs_new(bus
, &w
);
3146 return log_error_errno(r
, "Could not watch jobs: %m");
3150 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3152 wait_context
.unit_paths
= set_new(&string_hash_ops
);
3153 if (!wait_context
.unit_paths
)
3156 r
= sd_bus_call_method(
3158 "org.freedesktop.systemd1",
3159 "/org/freedesktop/systemd1",
3160 "org.freedesktop.systemd1.Manager",
3165 return log_error_errno(r
, "Failed to enable subscription: %s", bus_error_message(&error
, r
));
3166 r
= sd_event_default(&wait_context
.event
);
3168 return log_error_errno(r
, "Failed to allocate event loop: %m");
3169 r
= sd_bus_attach_event(bus
, wait_context
.event
, 0);
3171 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
3174 STRV_FOREACH(name
, names
) {
3175 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3178 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
, arg_wait
? &wait_context
: NULL
);
3179 if (r
>= 0 && q
< 0)
3180 r
= translate_bus_error_to_exit_status(q
, &error
);
3183 if (!arg_no_block
) {
3184 int q
, arg_count
= 0;
3185 const char* extra_args
[4] = {};
3187 if (arg_scope
!= UNIT_FILE_SYSTEM
)
3188 extra_args
[arg_count
++] = "--user";
3190 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
3191 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
3192 extra_args
[arg_count
++] = "-H";
3193 extra_args
[arg_count
++] = arg_host
;
3194 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
3195 extra_args
[arg_count
++] = "-M";
3196 extra_args
[arg_count
++] = arg_host
;
3199 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
3203 /* When stopping units, warn if they can still be triggered by
3204 * another active unit (socket, path, timer) */
3205 if (!arg_quiet
&& streq(method
, "StopUnit"))
3206 STRV_FOREACH(name
, names
)
3207 check_triggering_units(bus
, *name
);
3210 if (r
>= 0 && arg_wait
) {
3212 q
= sd_event_loop(wait_context
.event
);
3214 return log_error_errno(q
, "Failed to run event loop: %m");
3215 if (wait_context
.any_failed
)
3223 static int logind_set_wall_message(void) {
3224 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3226 _cleanup_free_
char *m
= NULL
;
3229 r
= acquire_bus(BUS_FULL
, &bus
);
3233 m
= strv_join(arg_wall
, " ");
3237 r
= sd_bus_call_method(
3239 "org.freedesktop.login1",
3240 "/org/freedesktop/login1",
3241 "org.freedesktop.login1.Manager",
3250 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
3255 /* Ask systemd-logind, which might grant access to unprivileged users
3256 * through PolicyKit */
3257 static int logind_reboot(enum action a
) {
3259 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3260 const char *method
, *description
;
3264 r
= acquire_bus(BUS_FULL
, &bus
);
3270 case ACTION_POWEROFF
:
3271 method
= "PowerOff";
3272 description
= "power off system";
3277 description
= "reboot system";
3282 description
= "halt system";
3285 case ACTION_SUSPEND
:
3287 description
= "suspend system";
3290 case ACTION_HIBERNATE
:
3291 method
= "Hibernate";
3292 description
= "hibernate system";
3295 case ACTION_HYBRID_SLEEP
:
3296 method
= "HybridSleep";
3297 description
= "put system into hybrid sleep";
3304 polkit_agent_open_if_enabled();
3305 (void) logind_set_wall_message();
3307 r
= sd_bus_call_method(
3309 "org.freedesktop.login1",
3310 "/org/freedesktop/login1",
3311 "org.freedesktop.login1.Manager",
3315 "b", arg_ask_password
);
3317 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
3325 static int logind_check_inhibitors(enum action a
) {
3327 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3328 _cleanup_strv_free_
char **sessions
= NULL
;
3329 const char *what
, *who
, *why
, *mode
;
3336 if (arg_ignore_inhibitors
|| arg_force
> 0)
3348 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
3351 r
= acquire_bus(BUS_FULL
, &bus
);
3355 r
= sd_bus_call_method(
3357 "org.freedesktop.login1",
3358 "/org/freedesktop/login1",
3359 "org.freedesktop.login1.Manager",
3365 /* If logind is not around, then there are no inhibitors... */
3368 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3370 return bus_log_parse_error(r
);
3372 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3373 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3374 _cleanup_strv_free_
char **sv
= NULL
;
3376 if (!streq(mode
, "block"))
3379 sv
= strv_split(what
, ":");
3383 if (!pid_is_valid((pid_t
) pid
)) {
3384 log_error("Invalid PID "PID_FMT
".", (pid_t
) pid
);
3388 if (!strv_contains(sv
,
3393 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3396 get_process_comm(pid
, &comm
);
3397 user
= uid_to_name(uid
);
3399 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3400 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3405 return bus_log_parse_error(r
);
3407 r
= sd_bus_message_exit_container(reply
);
3409 return bus_log_parse_error(r
);
3411 /* Check for current sessions */
3412 sd_get_sessions(&sessions
);
3413 STRV_FOREACH(s
, sessions
) {
3414 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3416 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3419 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3422 if (sd_session_get_type(*s
, &type
) < 0 || !STR_IN_SET(type
, "x11", "tty"))
3425 sd_session_get_tty(*s
, &tty
);
3426 sd_session_get_seat(*s
, &seat
);
3427 sd_session_get_service(*s
, &service
);
3428 user
= uid_to_name(uid
);
3430 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3437 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3438 action_table
[a
].verb
);
3446 static int logind_prepare_firmware_setup(void) {
3448 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3452 r
= acquire_bus(BUS_FULL
, &bus
);
3456 r
= sd_bus_call_method(
3458 "org.freedesktop.login1",
3459 "/org/freedesktop/login1",
3460 "org.freedesktop.login1.Manager",
3461 "SetRebootToFirmwareSetup",
3466 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3470 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3475 static int prepare_firmware_setup(void) {
3478 if (!arg_firmware_setup
)
3481 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3483 r
= efi_set_reboot_to_firmware(true);
3485 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3490 return logind_prepare_firmware_setup();
3493 static int set_exit_code(uint8_t code
) {
3494 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3498 r
= acquire_bus(BUS_MANAGER
, &bus
);
3502 r
= sd_bus_call_method(
3504 "org.freedesktop.systemd1",
3505 "/org/freedesktop/systemd1",
3506 "org.freedesktop.systemd1.Manager",
3512 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3517 static int start_special(int argc
, char *argv
[], void *userdata
) {
3520 bool termination_action
; /* an action that terminates the manager,
3521 * can be performed also by signal. */
3525 a
= verb_to_action(argv
[0]);
3527 r
= logind_check_inhibitors(a
);
3531 if (arg_force
>= 2 && geteuid() != 0) {
3532 log_error("Must be root.");
3536 r
= prepare_firmware_setup();
3540 if (a
== ACTION_REBOOT
&& argc
> 1) {
3541 r
= update_reboot_parameter_and_warn(argv
[1]);
3545 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3548 /* If the exit code is not given on the command line,
3549 * don't reset it to zero: just keep it as it might
3550 * have been set previously. */
3552 r
= safe_atou8(argv
[1], &code
);
3554 return log_error_errno(r
, "Invalid exit code.");
3556 r
= set_exit_code(code
);
3561 termination_action
= IN_SET(a
,
3565 if (termination_action
&& arg_force
>= 2)
3568 if (arg_force
>= 1 &&
3569 (termination_action
|| IN_SET(a
, ACTION_KEXEC
, ACTION_EXIT
)))
3570 r
= trivial_method(argc
, argv
, userdata
);
3572 /* First try logind, to allow authentication with polkit */
3579 ACTION_HYBRID_SLEEP
)) {
3581 r
= logind_reboot(a
);
3584 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3585 /* requested operation is not supported or already in progress */
3588 /* On all other errors, try low-level operation. In order to minimize the difference between
3589 * operation with and without logind, we explicitly enable non-blocking mode for this, as
3590 * logind's shutdown operations are always non-blocking. */
3592 arg_no_block
= true;
3594 } else if (IN_SET(a
, ACTION_EXIT
, ACTION_KEXEC
))
3595 /* Since exit/kexec are so close in behaviour to power-off/reboot, let's also make them
3596 * asynchronous, in order to not confuse the user needlessly with unexpected behaviour. */
3597 arg_no_block
= true;
3599 r
= start_unit(argc
, argv
, userdata
);
3602 if (termination_action
&& arg_force
< 2 &&
3603 IN_SET(r
, -ENOENT
, -ETIMEDOUT
))
3604 log_notice("It is possible to perform action directly, see discussion of --force --force in man:systemctl(1).");
3609 static int start_system_special(int argc
, char *argv
[], void *userdata
) {
3610 /* Like start_special above, but raises an error when running in user mode */
3612 if (arg_scope
!= UNIT_FILE_SYSTEM
) {
3613 log_error("Bad action for %s mode.",
3614 arg_scope
== UNIT_FILE_GLOBAL
? "--global" : "--user");
3618 return start_special(argc
, argv
, userdata
);
3621 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3622 _cleanup_strv_free_
char **names
= NULL
;
3623 UnitActiveState active_state
;
3629 r
= acquire_bus(BUS_MANAGER
, &bus
);
3633 r
= expand_names(bus
, args
, NULL
, &names
);
3635 return log_error_errno(r
, "Failed to expand names: %m");
3637 STRV_FOREACH(name
, names
) {
3638 r
= get_state_one_unit(bus
, *name
, &active_state
);
3643 puts(unit_active_state_to_string(active_state
));
3645 for (i
= 0; i
< nb_states
; ++i
)
3646 if (good_states
[i
] == active_state
)
3650 /* use the given return code for the case that we won't find
3651 * any unit which matches the list */
3652 return found
? 0 : code
;
3655 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3656 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3657 /* According to LSB: 3, "program is not running" */
3658 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3661 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3662 const UnitActiveState states
[] = { UNIT_FAILED
};
3663 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3666 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3667 _cleanup_strv_free_
char **names
= NULL
;
3668 char *kill_who
= NULL
, **name
;
3672 r
= acquire_bus(BUS_MANAGER
, &bus
);
3676 polkit_agent_open_if_enabled();
3679 arg_kill_who
= "all";
3681 /* --fail was specified */
3682 if (streq(arg_job_mode
, "fail"))
3683 kill_who
= strjoina(arg_kill_who
, "-fail");
3685 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3687 return log_error_errno(r
, "Failed to expand names: %m");
3689 STRV_FOREACH(name
, names
) {
3690 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3692 q
= sd_bus_call_method(
3694 "org.freedesktop.systemd1",
3695 "/org/freedesktop/systemd1",
3696 "org.freedesktop.systemd1.Manager",
3700 "ssi", *name
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3702 log_error_errno(q
, "Failed to kill unit %s: %s", *name
, bus_error_message(&error
, q
));
3711 typedef struct ExecStatusInfo
{
3719 usec_t start_timestamp
;
3720 usec_t exit_timestamp
;
3725 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3728 static void exec_status_info_free(ExecStatusInfo
*i
) {
3737 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3738 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3741 int32_t code
, status
;
3747 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3749 return bus_log_parse_error(r
);
3753 r
= sd_bus_message_read(m
, "s", &path
);
3755 return bus_log_parse_error(r
);
3757 i
->path
= strdup(path
);
3761 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3763 return bus_log_parse_error(r
);
3765 r
= sd_bus_message_read(m
,
3768 &start_timestamp
, &start_timestamp_monotonic
,
3769 &exit_timestamp
, &exit_timestamp_monotonic
,
3773 return bus_log_parse_error(r
);
3776 i
->start_timestamp
= (usec_t
) start_timestamp
;
3777 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3778 i
->pid
= (pid_t
) pid
;
3782 r
= sd_bus_message_exit_container(m
);
3784 return bus_log_parse_error(r
);
3789 typedef struct UnitCondition
{
3796 LIST_FIELDS(struct UnitCondition
, conditions
);
3799 static void unit_condition_free(UnitCondition
*c
) {
3808 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition
*, unit_condition_free
);
3810 typedef struct UnitStatusInfo
{
3812 const char *load_state
;
3813 const char *active_state
;
3814 const char *sub_state
;
3815 const char *unit_file_state
;
3816 const char *unit_file_preset
;
3818 const char *description
;
3819 const char *following
;
3821 char **documentation
;
3823 const char *fragment_path
;
3824 const char *source_path
;
3825 const char *control_group
;
3827 char **dropin_paths
;
3829 const char *load_error
;
3832 usec_t inactive_exit_timestamp
;
3833 usec_t inactive_exit_timestamp_monotonic
;
3834 usec_t active_enter_timestamp
;
3835 usec_t active_exit_timestamp
;
3836 usec_t inactive_enter_timestamp
;
3838 bool need_daemon_reload
;
3844 const char *status_text
;
3845 const char *pid_file
;
3849 usec_t start_timestamp
;
3850 usec_t exit_timestamp
;
3852 int exit_code
, exit_status
;
3854 usec_t condition_timestamp
;
3855 bool condition_result
;
3856 LIST_HEAD(UnitCondition
, conditions
);
3858 usec_t assert_timestamp
;
3860 bool failed_assert_trigger
;
3861 bool failed_assert_negate
;
3862 const char *failed_assert
;
3863 const char *failed_assert_parameter
;
3864 usec_t next_elapse_real
;
3865 usec_t next_elapse_monotonic
;
3868 unsigned n_accepted
;
3869 unsigned n_connections
;
3872 /* Pairs of type, path */
3876 const char *sysfs_path
;
3878 /* Mount, Automount */
3885 uint64_t memory_current
;
3886 uint64_t memory_low
;
3887 uint64_t memory_high
;
3888 uint64_t memory_max
;
3889 uint64_t memory_swap_max
;
3890 uint64_t memory_limit
;
3891 uint64_t cpu_usage_nsec
;
3892 uint64_t tasks_current
;
3895 uint64_t ip_ingress_bytes
;
3896 uint64_t ip_egress_bytes
;
3898 LIST_HEAD(ExecStatusInfo
, exec
);
3901 static void unit_status_info_free(UnitStatusInfo
*info
) {
3905 strv_free(info
->documentation
);
3906 strv_free(info
->dropin_paths
);
3907 strv_free(info
->listen
);
3909 while ((c
= info
->conditions
)) {
3910 LIST_REMOVE(conditions
, info
->conditions
, c
);
3911 unit_condition_free(c
);
3914 while ((p
= info
->exec
)) {
3915 LIST_REMOVE(exec
, info
->exec
, p
);
3916 exec_status_info_free(p
);
3920 static void print_status_info(
3926 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3928 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3929 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3936 /* This shows pretty information about a unit. See
3937 * print_property() for a low-level property printer */
3939 if (streq_ptr(i
->active_state
, "failed")) {
3940 active_on
= ansi_highlight_red();
3941 active_off
= ansi_normal();
3942 } else if (STRPTR_IN_SET(i
->active_state
, "active", "reloading")) {
3943 active_on
= ansi_highlight_green();
3944 active_off
= ansi_normal();
3946 active_on
= active_off
= "";
3948 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3950 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3951 printf(" - %s", i
->description
);
3956 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3958 if (streq_ptr(i
->load_state
, "error")) {
3959 on
= ansi_highlight_red();
3960 off
= ansi_normal();
3964 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3966 if (i
->load_error
!= 0)
3967 printf(" Loaded: %s%s%s (Reason: %s)\n",
3968 on
, strna(i
->load_state
), off
, i
->load_error
);
3969 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3970 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3971 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3972 else if (path
&& !isempty(i
->unit_file_state
))
3973 printf(" Loaded: %s%s%s (%s; %s)\n",
3974 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3976 printf(" Loaded: %s%s%s (%s)\n",
3977 on
, strna(i
->load_state
), off
, path
);
3979 printf(" Loaded: %s%s%s\n",
3980 on
, strna(i
->load_state
), off
);
3983 printf("Transient: yes\n");
3985 if (!strv_isempty(i
->dropin_paths
)) {
3986 _cleanup_free_
char *dir
= NULL
;
3990 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3991 if (! dir
|| last
) {
3992 printf(dir
? " " : " Drop-In: ");
3996 dir
= dirname_malloc(*dropin
);
4002 printf("%s\n %s", dir
,
4003 special_glyph(TREE_RIGHT
));
4006 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
4008 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
4012 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
4014 printf(" Active: %s%s (%s)%s",
4015 active_on
, strna(i
->active_state
), ss
, active_off
);
4017 printf(" Active: %s%s%s",
4018 active_on
, strna(i
->active_state
), active_off
);
4020 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
4021 printf(" (Result: %s)", i
->result
);
4023 timestamp
= STRPTR_IN_SET(i
->active_state
, "active", "reloading") ? i
->active_enter_timestamp
:
4024 STRPTR_IN_SET(i
->active_state
, "inactive", "failed") ? i
->inactive_enter_timestamp
:
4025 STRPTR_IN_SET(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
4026 i
->active_exit_timestamp
;
4028 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
4029 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
4032 printf(" since %s; %s\n", s2
, s1
);
4034 printf(" since %s\n", s2
);
4038 if (endswith(i
->id
, ".timer")) {
4039 char tstamp1
[FORMAT_TIMESTAMP_RELATIVE_MAX
],
4040 tstamp2
[FORMAT_TIMESTAMP_MAX
];
4041 char *next_rel_time
, *next_time
;
4042 dual_timestamp nw
, next
= {i
->next_elapse_real
,
4043 i
->next_elapse_monotonic
};
4046 printf(" Trigger: ");
4048 dual_timestamp_get(&nw
);
4049 next_elapse
= calc_next_elapse(&nw
, &next
);
4050 next_rel_time
= format_timestamp_relative(tstamp1
,
4053 next_time
= format_timestamp(tstamp2
,
4057 if (next_time
&& next_rel_time
)
4058 printf("%s; %s\n", next_time
, next_rel_time
);
4063 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
4067 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
4068 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
4070 printf("Condition: start %scondition failed%s at %s%s%s\n",
4071 ansi_highlight_yellow(), ansi_normal(),
4072 s2
, s1
? "; " : "", strempty(s1
));
4074 LIST_FOREACH(conditions
, c
, i
->conditions
)
4075 if (c
->tristate
< 0)
4078 LIST_FOREACH(conditions
, c
, i
->conditions
)
4079 if (c
->tristate
< 0)
4080 printf(" %s %s=%s%s%s was not met\n",
4081 --n
? special_glyph(TREE_BRANCH
) : special_glyph(TREE_RIGHT
),
4083 c
->trigger
? "|" : "",
4084 c
->negate
? "!" : "",
4088 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
4089 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
4090 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
4092 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
4093 ansi_highlight_red(), ansi_normal(),
4094 s2
, s1
? "; " : "", strempty(s1
));
4095 if (i
->failed_assert_trigger
)
4096 printf(" none of the trigger assertions were met\n");
4097 else if (i
->failed_assert
)
4098 printf(" %s=%s%s was not met\n",
4100 i
->failed_assert_negate
? "!" : "",
4101 i
->failed_assert_parameter
);
4105 printf(" Device: %s\n", i
->sysfs_path
);
4107 printf(" Where: %s\n", i
->where
);
4109 printf(" What: %s\n", i
->what
);
4111 STRV_FOREACH(t
, i
->documentation
)
4112 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
4114 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
4115 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
4118 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
4120 LIST_FOREACH(exec
, p
, i
->exec
) {
4121 _cleanup_free_
char *argv
= NULL
;
4124 /* Only show exited processes here */
4128 argv
= strv_join(p
->argv
, " ");
4129 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
4131 good
= is_clean_exit(p
->code
, p
->status
, EXIT_CLEAN_DAEMON
, NULL
);
4133 on
= ansi_highlight_red();
4134 off
= ansi_normal();
4138 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
4140 if (p
->code
== CLD_EXITED
) {
4143 printf("status=%i", p
->status
);
4145 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
4150 printf("signal=%s", signal_to_string(p
->status
));
4152 printf(")%s\n", off
);
4154 if (i
->main_pid
== p
->pid
&&
4155 i
->start_timestamp
== p
->start_timestamp
&&
4156 i
->exit_timestamp
== p
->start_timestamp
)
4157 /* Let's not show this twice */
4160 if (p
->pid
== i
->control_pid
)
4164 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
4165 if (i
->main_pid
> 0) {
4166 printf(" Main PID: "PID_FMT
, i
->main_pid
);
4169 _cleanup_free_
char *comm
= NULL
;
4170 (void) get_process_comm(i
->main_pid
, &comm
);
4172 printf(" (%s)", comm
);
4173 } else if (i
->exit_code
> 0) {
4174 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
4176 if (i
->exit_code
== CLD_EXITED
) {
4179 printf("status=%i", i
->exit_status
);
4181 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
4186 printf("signal=%s", signal_to_string(i
->exit_status
));
4191 if (i
->control_pid
> 0) {
4192 _cleanup_free_
char *c
= NULL
;
4194 if (i
->main_pid
> 0)
4195 fputs("; Control PID: ", stdout
);
4197 fputs("Cntrl PID: ", stdout
); /* if first in column, abbreviated so it fits alignment */
4199 printf(PID_FMT
, i
->control_pid
);
4201 (void) get_process_comm(i
->control_pid
, &c
);
4210 printf(" Status: \"%s\"\n", i
->status_text
);
4211 if (i
->status_errno
> 0)
4212 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
4214 if (i
->ip_ingress_bytes
!= (uint64_t) -1 && i
->ip_egress_bytes
!= (uint64_t) -1) {
4215 char buf_in
[FORMAT_BYTES_MAX
], buf_out
[FORMAT_BYTES_MAX
];
4217 printf(" IP: %s in, %s out\n",
4218 format_bytes(buf_in
, sizeof(buf_in
), i
->ip_ingress_bytes
),
4219 format_bytes(buf_out
, sizeof(buf_out
), i
->ip_egress_bytes
));
4222 if (i
->tasks_current
!= (uint64_t) -1) {
4223 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
4225 if (i
->tasks_max
!= (uint64_t) -1)
4226 printf(" (limit: %" PRIu64
")\n", i
->tasks_max
);
4231 if (i
->memory_current
!= (uint64_t) -1) {
4232 char buf
[FORMAT_BYTES_MAX
];
4234 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
4236 if (i
->memory_low
> 0 || i
->memory_high
!= CGROUP_LIMIT_MAX
||
4237 i
->memory_max
!= CGROUP_LIMIT_MAX
|| i
->memory_swap_max
!= CGROUP_LIMIT_MAX
||
4238 i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4239 const char *prefix
= "";
4242 if (i
->memory_low
> 0) {
4243 printf("%slow: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_low
));
4246 if (i
->memory_high
!= CGROUP_LIMIT_MAX
) {
4247 printf("%shigh: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_high
));
4250 if (i
->memory_max
!= CGROUP_LIMIT_MAX
) {
4251 printf("%smax: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_max
));
4254 if (i
->memory_swap_max
!= CGROUP_LIMIT_MAX
) {
4255 printf("%sswap max: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_swap_max
));
4258 if (i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4259 printf("%slimit: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
4267 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
4268 char buf
[FORMAT_TIMESPAN_MAX
];
4269 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
4272 if (i
->control_group
) {
4273 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4274 static const char prefix
[] = " ";
4277 printf(" CGroup: %s\n", i
->control_group
);
4280 if (c
> sizeof(prefix
) - 1)
4281 c
-= sizeof(prefix
) - 1;
4285 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
4290 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4292 if (i
->main_pid
> 0)
4293 extra
[k
++] = i
->main_pid
;
4295 if (i
->control_pid
> 0)
4296 extra
[k
++] = i
->control_pid
;
4298 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
4300 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
4303 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
4304 show_journal_by_unit(
4309 i
->inactive_exit_timestamp_monotonic
,
4312 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
4313 SD_JOURNAL_LOCAL_ONLY
,
4314 arg_scope
== UNIT_FILE_SYSTEM
,
4317 if (i
->need_daemon_reload
)
4318 warn_unit_file_changed(i
->id
);
4321 static void show_unit_help(UnitStatusInfo
*i
) {
4326 if (!i
->documentation
) {
4327 log_info("Documentation for %s not known.", i
->id
);
4331 STRV_FOREACH(p
, i
->documentation
)
4332 if (startswith(*p
, "man:"))
4333 show_man_page(*p
+ 4, false);
4335 log_info("Can't show: %s", *p
);
4338 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
4345 switch (contents
[0]) {
4347 case SD_BUS_TYPE_STRING
: {
4350 r
= sd_bus_message_read(m
, "s", &s
);
4352 return bus_log_parse_error(r
);
4355 if (streq(name
, "Id"))
4357 else if (streq(name
, "LoadState"))
4359 else if (streq(name
, "ActiveState"))
4360 i
->active_state
= s
;
4361 else if (streq(name
, "SubState"))
4363 else if (streq(name
, "Description"))
4365 else if (streq(name
, "FragmentPath"))
4366 i
->fragment_path
= s
;
4367 else if (streq(name
, "SourcePath"))
4370 else if (streq(name
, "DefaultControlGroup")) {
4372 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
4374 i
->control_group
= e
;
4377 else if (streq(name
, "ControlGroup"))
4378 i
->control_group
= s
;
4379 else if (streq(name
, "StatusText"))
4381 else if (streq(name
, "PIDFile"))
4383 else if (streq(name
, "SysFSPath"))
4385 else if (streq(name
, "Where"))
4387 else if (streq(name
, "What"))
4389 else if (streq(name
, "Following"))
4391 else if (streq(name
, "UnitFileState"))
4392 i
->unit_file_state
= s
;
4393 else if (streq(name
, "UnitFilePreset"))
4394 i
->unit_file_preset
= s
;
4395 else if (streq(name
, "Result"))
4402 case SD_BUS_TYPE_BOOLEAN
: {
4405 r
= sd_bus_message_read(m
, "b", &b
);
4407 return bus_log_parse_error(r
);
4409 if (streq(name
, "Accept"))
4411 else if (streq(name
, "NeedDaemonReload"))
4412 i
->need_daemon_reload
= b
;
4413 else if (streq(name
, "ConditionResult"))
4414 i
->condition_result
= b
;
4415 else if (streq(name
, "AssertResult"))
4416 i
->assert_result
= b
;
4417 else if (streq(name
, "Transient"))
4423 case SD_BUS_TYPE_UINT32
: {
4426 r
= sd_bus_message_read(m
, "u", &u
);
4428 return bus_log_parse_error(r
);
4430 if (streq(name
, "MainPID")) {
4432 i
->main_pid
= (pid_t
) u
;
4435 } else if (streq(name
, "ControlPID"))
4436 i
->control_pid
= (pid_t
) u
;
4437 else if (streq(name
, "ExecMainPID")) {
4439 i
->main_pid
= (pid_t
) u
;
4440 } else if (streq(name
, "NAccepted"))
4442 else if (streq(name
, "NConnections"))
4443 i
->n_connections
= u
;
4448 case SD_BUS_TYPE_INT32
: {
4451 r
= sd_bus_message_read(m
, "i", &j
);
4453 return bus_log_parse_error(r
);
4455 if (streq(name
, "ExecMainCode"))
4456 i
->exit_code
= (int) j
;
4457 else if (streq(name
, "ExecMainStatus"))
4458 i
->exit_status
= (int) j
;
4459 else if (streq(name
, "StatusErrno"))
4460 i
->status_errno
= (int) j
;
4465 case SD_BUS_TYPE_UINT64
: {
4468 r
= sd_bus_message_read(m
, "t", &u
);
4470 return bus_log_parse_error(r
);
4472 if (streq(name
, "ExecMainStartTimestamp"))
4473 i
->start_timestamp
= (usec_t
) u
;
4474 else if (streq(name
, "ExecMainExitTimestamp"))
4475 i
->exit_timestamp
= (usec_t
) u
;
4476 else if (streq(name
, "ActiveEnterTimestamp"))
4477 i
->active_enter_timestamp
= (usec_t
) u
;
4478 else if (streq(name
, "InactiveEnterTimestamp"))
4479 i
->inactive_enter_timestamp
= (usec_t
) u
;
4480 else if (streq(name
, "InactiveExitTimestamp"))
4481 i
->inactive_exit_timestamp
= (usec_t
) u
;
4482 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4483 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4484 else if (streq(name
, "ActiveExitTimestamp"))
4485 i
->active_exit_timestamp
= (usec_t
) u
;
4486 else if (streq(name
, "ConditionTimestamp"))
4487 i
->condition_timestamp
= (usec_t
) u
;
4488 else if (streq(name
, "AssertTimestamp"))
4489 i
->assert_timestamp
= (usec_t
) u
;
4490 else if (streq(name
, "MemoryCurrent"))
4491 i
->memory_current
= u
;
4492 else if (streq(name
, "MemoryLow"))
4494 else if (streq(name
, "MemoryHigh"))
4496 else if (streq(name
, "MemoryMax"))
4498 else if (streq(name
, "MemorySwapMax"))
4499 i
->memory_swap_max
= u
;
4500 else if (streq(name
, "MemoryLimit"))
4501 i
->memory_limit
= u
;
4502 else if (streq(name
, "TasksCurrent"))
4503 i
->tasks_current
= u
;
4504 else if (streq(name
, "TasksMax"))
4506 else if (streq(name
, "CPUUsageNSec"))
4507 i
->cpu_usage_nsec
= u
;
4508 else if (streq(name
, "NextElapseUSecMonotonic"))
4509 i
->next_elapse_monotonic
= u
;
4510 else if (streq(name
, "NextElapseUSecRealtime"))
4511 i
->next_elapse_real
= u
;
4512 else if (streq(name
, "IPIngressBytes"))
4513 i
->ip_ingress_bytes
= u
;
4514 else if (streq(name
, "IPEgressBytes"))
4515 i
->ip_egress_bytes
= u
;
4520 case SD_BUS_TYPE_ARRAY
:
4522 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4523 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4525 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4527 return bus_log_parse_error(r
);
4529 info
= new0(ExecStatusInfo
, 1);
4533 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4535 info
->name
= strdup(name
);
4539 LIST_PREPEND(exec
, i
->exec
, info
);
4541 info
= new0(ExecStatusInfo
, 1);
4547 return bus_log_parse_error(r
);
4549 r
= sd_bus_message_exit_container(m
);
4551 return bus_log_parse_error(r
);
4555 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4556 const char *type
, *path
;
4558 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4560 return bus_log_parse_error(r
);
4562 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4564 r
= strv_extend(&i
->listen
, type
);
4568 r
= strv_extend(&i
->listen
, path
);
4573 return bus_log_parse_error(r
);
4575 r
= sd_bus_message_exit_container(m
);
4577 return bus_log_parse_error(r
);
4581 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4583 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4585 return bus_log_parse_error(r
);
4587 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4589 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4591 return bus_log_parse_error(r
);
4593 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4594 const char *cond
, *param
;
4595 int trigger
, negate
;
4598 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4600 return bus_log_parse_error(r
);
4602 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4603 _cleanup_(unit_condition_freep
) UnitCondition
*c
= NULL
;
4605 log_debug("%s trigger=%d negate=%d %s →%d", cond
, trigger
, negate
, param
, state
);
4607 c
= new0(UnitCondition
, 1);
4611 c
->name
= strdup(cond
);
4612 c
->param
= strdup(param
);
4613 if (!c
->name
|| !c
->param
)
4616 c
->trigger
= trigger
;
4618 c
->tristate
= state
;
4620 LIST_PREPEND(conditions
, i
->conditions
, c
);
4624 return bus_log_parse_error(r
);
4626 r
= sd_bus_message_exit_container(m
);
4628 return bus_log_parse_error(r
);
4630 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4631 const char *cond
, *param
;
4632 int trigger
, negate
;
4635 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4637 return bus_log_parse_error(r
);
4639 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4640 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4641 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4642 i
->failed_assert
= cond
;
4643 i
->failed_assert_trigger
= trigger
;
4644 i
->failed_assert_negate
= negate
;
4645 i
->failed_assert_parameter
= param
;
4649 return bus_log_parse_error(r
);
4651 r
= sd_bus_message_exit_container(m
);
4653 return bus_log_parse_error(r
);
4660 case SD_BUS_TYPE_STRUCT_BEGIN
:
4662 if (streq(name
, "LoadError")) {
4663 const char *n
, *message
;
4665 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4667 return bus_log_parse_error(r
);
4669 if (!isempty(message
))
4670 i
->load_error
= message
;
4683 r
= sd_bus_message_skip(m
, contents
);
4685 return bus_log_parse_error(r
);
4690 #define print_prop(name, fmt, ...) \
4693 printf(fmt "\n", __VA_ARGS__); \
4695 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4698 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4704 /* This is a low-level property printer, see
4705 * print_status_info() for the nicer output */
4707 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4708 /* skip what we didn't read */
4709 r
= sd_bus_message_skip(m
, contents
);
4713 switch (contents
[0]) {
4715 case SD_BUS_TYPE_STRUCT_BEGIN
:
4717 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4720 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4722 return bus_log_parse_error(r
);
4725 print_prop(name
, "%"PRIu32
, u
);
4727 print_prop(name
, "%s", "");
4731 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4734 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4736 return bus_log_parse_error(r
);
4738 if (arg_all
|| !isempty(s
))
4739 print_prop(name
, "%s", s
);
4743 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4744 const char *a
= NULL
, *b
= NULL
;
4746 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4748 return bus_log_parse_error(r
);
4750 if (arg_all
|| !isempty(a
) || !isempty(b
))
4751 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4754 } else if (streq_ptr(name
, "SystemCallFilter")) {
4755 _cleanup_strv_free_
char **l
= NULL
;
4758 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4760 return bus_log_parse_error(r
);
4762 r
= sd_bus_message_read(m
, "b", &whitelist
);
4764 return bus_log_parse_error(r
);
4766 r
= sd_bus_message_read_strv(m
, &l
);
4768 return bus_log_parse_error(r
);
4770 r
= sd_bus_message_exit_container(m
);
4772 return bus_log_parse_error(r
);
4774 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4779 fputs(name
, stdout
);
4786 STRV_FOREACH(i
, l
) {
4794 fputc('\n', stdout
);
4802 case SD_BUS_TYPE_ARRAY
:
4804 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4808 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4810 return bus_log_parse_error(r
);
4812 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4813 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path
, yes_no(ignore
));
4816 return bus_log_parse_error(r
);
4818 r
= sd_bus_message_exit_container(m
);
4820 return bus_log_parse_error(r
);
4824 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4825 const char *type
, *path
;
4827 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4829 return bus_log_parse_error(r
);
4831 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4832 print_prop(type
, "%s", path
);
4834 return bus_log_parse_error(r
);
4836 r
= sd_bus_message_exit_container(m
);
4838 return bus_log_parse_error(r
);
4842 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4843 const char *type
, *path
;
4845 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4847 return bus_log_parse_error(r
);
4849 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4853 printf("Listen%s=%s\n", type
, path
);
4855 return bus_log_parse_error(r
);
4857 r
= sd_bus_message_exit_container(m
);
4859 return bus_log_parse_error(r
);
4863 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4865 uint64_t value
, next_elapse
;
4867 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4869 return bus_log_parse_error(r
);
4871 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4872 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4874 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4875 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4876 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4879 return bus_log_parse_error(r
);
4881 r
= sd_bus_message_exit_container(m
);
4883 return bus_log_parse_error(r
);
4887 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4888 ExecStatusInfo info
= {};
4890 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4892 return bus_log_parse_error(r
);
4894 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4895 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4896 _cleanup_free_
char *tt
;
4898 tt
= strv_join(info
.argv
, " ");
4901 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4904 yes_no(info
.ignore
),
4905 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4906 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4908 sigchld_code_to_string(info
.code
),
4910 info
.code
== CLD_EXITED
? "" : "/",
4911 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4914 strv_free(info
.argv
);
4918 r
= sd_bus_message_exit_container(m
);
4920 return bus_log_parse_error(r
);
4924 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4925 const char *path
, *rwm
;
4927 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4929 return bus_log_parse_error(r
);
4931 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4932 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4934 return bus_log_parse_error(r
);
4936 r
= sd_bus_message_exit_container(m
);
4938 return bus_log_parse_error(r
);
4942 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4943 STR_IN_SET(name
, "IODeviceWeight", "BlockIODeviceWeight")) {
4947 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4949 return bus_log_parse_error(r
);
4951 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4952 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4954 return bus_log_parse_error(r
);
4956 r
= sd_bus_message_exit_container(m
);
4958 return bus_log_parse_error(r
);
4962 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4963 (cgroup_io_limit_type_from_string(name
) >= 0 ||
4964 STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
4968 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4970 return bus_log_parse_error(r
);
4972 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4973 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4975 return bus_log_parse_error(r
);
4977 r
= sd_bus_message_exit_container(m
);
4979 return bus_log_parse_error(r
);
4987 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4989 return bus_log_parse_error(r
);
4992 r
= sd_bus_message_skip(m
, contents
);
4994 return bus_log_parse_error(r
);
4997 printf("%s=[unprintable]\n", name
);
5003 static int show_one(
5008 bool show_properties
,
5012 static const struct bus_properties_map property_map
[] = {
5013 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
5014 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
) },
5018 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5019 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5020 _cleanup_set_free_ Set
*found_properties
= NULL
;
5021 _cleanup_(unit_status_info_free
) UnitStatusInfo info
= {
5022 .memory_current
= (uint64_t) -1,
5023 .memory_high
= CGROUP_LIMIT_MAX
,
5024 .memory_max
= CGROUP_LIMIT_MAX
,
5025 .memory_swap_max
= CGROUP_LIMIT_MAX
,
5026 .memory_limit
= (uint64_t) -1,
5027 .cpu_usage_nsec
= (uint64_t) -1,
5028 .tasks_current
= (uint64_t) -1,
5029 .tasks_max
= (uint64_t) -1,
5030 .ip_ingress_bytes
= (uint64_t) -1,
5031 .ip_egress_bytes
= (uint64_t) -1,
5038 log_debug("Showing one %s", path
);
5040 r
= sd_bus_call_method(
5042 "org.freedesktop.systemd1",
5044 "org.freedesktop.DBus.Properties",
5050 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
5053 r
= bus_message_map_all_properties(reply
, property_map
, &error
, &info
);
5055 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
5057 if (streq_ptr(info
.load_state
, "not-found") && streq_ptr(info
.active_state
, "inactive")) {
5058 log_full(streq(verb
, "status") ? LOG_ERR
: LOG_DEBUG
,
5059 "Unit %s could not be found.", unit
);
5061 if (streq(verb
, "status"))
5062 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
;
5064 if (!streq(verb
, "show"))
5068 r
= sd_bus_message_rewind(reply
, true);
5070 return log_error_errno(r
, "Failed to rewind: %s", bus_error_message(&error
, r
));
5073 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
5075 return bus_log_parse_error(r
);
5082 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
5083 const char *name
, *contents
;
5085 r
= sd_bus_message_read(reply
, "s", &name
);
5087 return bus_log_parse_error(r
);
5089 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
5091 return bus_log_parse_error(r
);
5093 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
5095 return bus_log_parse_error(r
);
5097 if (show_properties
) {
5098 r
= set_ensure_allocated(&found_properties
, &string_hash_ops
);
5102 r
= set_put(found_properties
, name
);
5103 if (r
< 0 && r
!= EEXIST
)
5106 r
= print_property(name
, reply
, contents
);
5108 r
= status_property(name
, reply
, &info
, contents
);
5112 r
= sd_bus_message_exit_container(reply
);
5114 return bus_log_parse_error(r
);
5116 r
= sd_bus_message_exit_container(reply
);
5118 return bus_log_parse_error(r
);
5121 return bus_log_parse_error(r
);
5123 r
= sd_bus_message_exit_container(reply
);
5125 return bus_log_parse_error(r
);
5128 if (show_properties
) {
5131 STRV_FOREACH(pp
, arg_properties
)
5132 if (!set_contains(found_properties
, *pp
))
5133 log_debug("Property %s does not exist.", *pp
);
5135 } else if (streq(verb
, "help"))
5136 show_unit_help(&info
);
5137 else if (streq(verb
, "status")) {
5138 print_status_info(bus
, &info
, ellipsized
);
5140 if (info
.active_state
&& !STR_IN_SET(info
.active_state
, "active", "reloading"))
5141 r
= EXIT_PROGRAM_NOT_RUNNING
;
5143 r
= EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
;
5149 static int get_unit_dbus_path_by_pid(
5154 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5155 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5159 r
= sd_bus_call_method(
5161 "org.freedesktop.systemd1",
5162 "/org/freedesktop/systemd1",
5163 "org.freedesktop.systemd1.Manager",
5169 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
5171 r
= sd_bus_message_read(reply
, "o", &u
);
5173 return bus_log_parse_error(r
);
5183 static int show_all(
5186 bool show_properties
,
5190 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5191 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
5196 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
5200 pager_open(arg_no_pager
, false);
5204 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
5206 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
5207 _cleanup_free_
char *p
= NULL
;
5209 p
= unit_dbus_path_from_name(u
->id
);
5213 r
= show_one(verb
, bus
, p
, u
->id
, show_properties
, new_line
, ellipsized
);
5216 else if (r
> 0 && ret
== 0)
5223 static int show_system_status(sd_bus
*bus
) {
5224 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
5225 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5226 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
5227 _cleanup_free_
char *hn
= NULL
;
5228 const char *on
, *off
;
5231 hn
= gethostname_malloc();
5235 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &error
, &mi
);
5237 return log_error_errno(r
, "Failed to read server status: %s", bus_error_message(&error
, r
));
5239 if (streq_ptr(mi
.state
, "degraded")) {
5240 on
= ansi_highlight_red();
5241 off
= ansi_normal();
5242 } else if (streq_ptr(mi
.state
, "running")) {
5243 on
= ansi_highlight_green();
5244 off
= ansi_normal();
5246 on
= ansi_highlight_yellow();
5247 off
= ansi_normal();
5250 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
5252 printf(" State: %s%s%s\n",
5253 on
, strna(mi
.state
), off
);
5255 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
5256 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
5258 printf(" Since: %s; %s\n",
5259 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
5260 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
5262 printf(" CGroup: %s\n", mi
.control_group
?: "/");
5263 if (IN_SET(arg_transport
,
5264 BUS_TRANSPORT_LOCAL
,
5265 BUS_TRANSPORT_MACHINE
)) {
5266 static const char prefix
[] = " ";
5270 if (c
> sizeof(prefix
) - 1)
5271 c
-= sizeof(prefix
) - 1;
5275 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
5281 static int show(int argc
, char *argv
[], void *userdata
) {
5282 bool show_properties
, show_status
, show_help
, new_line
= false;
5283 bool ellipsized
= false;
5289 show_properties
= streq(argv
[0], "show");
5290 show_status
= streq(argv
[0], "status");
5291 show_help
= streq(argv
[0], "help");
5293 if (show_help
&& argc
<= 1) {
5294 log_error("This command expects one or more unit names. Did you mean --help?");
5298 r
= acquire_bus(BUS_MANAGER
, &bus
);
5302 pager_open(arg_no_pager
, false);
5305 /* Increase max number of open files to 16K if we can, we
5306 * might needs this when browsing journal files, which might
5307 * be split up into many files. */
5308 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
5310 /* If no argument is specified inspect the manager itself */
5311 if (show_properties
&& argc
<= 1)
5312 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", NULL
, show_properties
, &new_line
, &ellipsized
);
5314 if (show_status
&& argc
<= 1) {
5316 show_system_status(bus
);
5320 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
5322 _cleanup_free_
char **patterns
= NULL
;
5325 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
5326 _cleanup_free_
char *path
= NULL
, *unit
= NULL
;
5329 if (safe_atou32(*name
, &id
) < 0) {
5330 if (strv_push(&patterns
, *name
) < 0)
5334 } else if (show_properties
) {
5335 /* Interpret as job id */
5336 if (asprintf(&path
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
5340 /* Interpret as PID */
5341 r
= get_unit_dbus_path_by_pid(bus
, id
, &path
);
5347 r
= unit_name_from_dbus_path(path
, &unit
);
5352 r
= show_one(argv
[0], bus
, path
, unit
, show_properties
, &new_line
, &ellipsized
);
5355 else if (r
> 0 && ret
== 0)
5359 if (!strv_isempty(patterns
)) {
5360 _cleanup_strv_free_
char **names
= NULL
;
5362 r
= expand_names(bus
, patterns
, NULL
, &names
);
5364 return log_error_errno(r
, "Failed to expand names: %m");
5366 STRV_FOREACH(name
, names
) {
5367 _cleanup_free_
char *path
;
5369 path
= unit_dbus_path_from_name(*name
);
5373 r
= show_one(argv
[0], bus
, path
, *name
, show_properties
, &new_line
, &ellipsized
);
5376 if (r
> 0 && ret
== 0)
5382 if (ellipsized
&& !arg_quiet
)
5383 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5388 static int cat_file(const char *filename
, bool newline
) {
5389 _cleanup_close_
int fd
;
5391 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
5395 printf("%s%s# %s%s\n",
5396 newline
? "\n" : "",
5397 ansi_highlight_blue(),
5402 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, 0);
5405 static int cat(int argc
, char *argv
[], void *userdata
) {
5406 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5407 _cleanup_strv_free_
char **names
= NULL
;
5413 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5414 log_error("Cannot remotely cat units.");
5418 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
5420 return log_error_errno(r
, "Failed to determine unit paths: %m");
5422 r
= acquire_bus(BUS_MANAGER
, &bus
);
5426 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5428 return log_error_errno(r
, "Failed to expand names: %m");
5430 pager_open(arg_no_pager
, false);
5432 STRV_FOREACH(name
, names
) {
5433 _cleanup_free_
char *fragment_path
= NULL
;
5434 _cleanup_strv_free_
char **dropin_paths
= NULL
;
5437 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
5448 if (need_daemon_reload(bus
, *name
) > 0) /* ignore errors (<0), this is informational output */
5450 "%s# Warning: %s changed on disk, the version systemd has loaded is outdated.\n"
5451 "%s# This output shows the current version of the unit's original fragment and drop-in files.\n"
5452 "%s# If fragments or drop-ins were added or removed, they are not properly reflected in this output.\n"
5453 "%s# Run 'systemctl%s daemon-reload' to reload units.%s\n",
5454 ansi_highlight_red(),
5456 ansi_highlight_red(),
5457 ansi_highlight_red(),
5458 ansi_highlight_red(),
5459 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
5462 if (fragment_path
) {
5463 r
= cat_file(fragment_path
, false);
5465 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
5468 STRV_FOREACH(path
, dropin_paths
) {
5469 r
= cat_file(*path
, path
== dropin_paths
);
5471 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
5478 static int set_property(int argc
, char *argv
[], void *userdata
) {
5479 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5480 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5481 _cleanup_free_
char *n
= NULL
;
5485 r
= acquire_bus(BUS_MANAGER
, &bus
);
5489 polkit_agent_open_if_enabled();
5491 r
= sd_bus_message_new_method_call(
5494 "org.freedesktop.systemd1",
5495 "/org/freedesktop/systemd1",
5496 "org.freedesktop.systemd1.Manager",
5497 "SetUnitProperties");
5499 return bus_log_create_error(r
);
5501 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
5503 return log_error_errno(r
, "Failed to mangle unit name: %m");
5505 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
5507 return bus_log_create_error(r
);
5509 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
5511 return bus_log_create_error(r
);
5513 r
= bus_append_unit_property_assignment_many(m
, strv_skip(argv
, 2));
5517 r
= sd_bus_message_close_container(m
);
5519 return bus_log_create_error(r
);
5521 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5523 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
5528 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5529 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5530 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5535 r
= acquire_bus(BUS_MANAGER
, &bus
);
5539 polkit_agent_open_if_enabled();
5541 switch (arg_action
) {
5548 method
= "Reexecute";
5551 case ACTION_SYSTEMCTL
:
5552 method
= streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5553 /* "daemon-reload" */ "Reload";
5557 assert_not_reached("Unexpected action");
5560 r
= sd_bus_message_new_method_call(
5563 "org.freedesktop.systemd1",
5564 "/org/freedesktop/systemd1",
5565 "org.freedesktop.systemd1.Manager",
5568 return bus_log_create_error(r
);
5570 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5571 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5572 * their timeout, and for everything else there's the same time budget in place. */
5574 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
5576 /* On reexecution, we expect a disconnect, not a reply */
5577 if (IN_SET(r
, -ETIMEDOUT
, -ECONNRESET
) && streq(method
, "Reexecute"))
5580 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5581 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5583 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5584 * old ways of doing things, hence don't log any error in that case here. */
5586 return r
< 0 ? r
: 0;
5589 static int trivial_method(int argc
, char *argv
[], void *userdata
) {
5590 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5595 r
= acquire_bus(BUS_MANAGER
, &bus
);
5599 polkit_agent_open_if_enabled();
5602 streq(argv
[0], "clear-jobs") ||
5603 streq(argv
[0], "cancel") ? "ClearJobs" :
5604 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5605 streq(argv
[0], "halt") ? "Halt" :
5606 streq(argv
[0], "reboot") ? "Reboot" :
5607 streq(argv
[0], "kexec") ? "KExec" :
5608 streq(argv
[0], "exit") ? "Exit" :
5609 /* poweroff */ "PowerOff";
5611 r
= sd_bus_call_method(
5613 "org.freedesktop.systemd1",
5614 "/org/freedesktop/systemd1",
5615 "org.freedesktop.systemd1.Manager",
5620 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5621 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5623 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5624 * old ways of doing things, hence don't log any error in that case here. */
5626 return r
< 0 ? r
: 0;
5629 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5630 _cleanup_strv_free_
char **names
= NULL
;
5636 return trivial_method(argc
, argv
, userdata
);
5638 r
= acquire_bus(BUS_MANAGER
, &bus
);
5642 polkit_agent_open_if_enabled();
5644 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5646 return log_error_errno(r
, "Failed to expand names: %m");
5648 STRV_FOREACH(name
, names
) {
5649 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5651 q
= sd_bus_call_method(
5653 "org.freedesktop.systemd1",
5654 "/org/freedesktop/systemd1",
5655 "org.freedesktop.systemd1.Manager",
5661 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5670 static int print_variable(const char *s
) {
5672 _cleanup_free_
char *esc
= NULL
;
5674 sep
= strchr(s
, '=');
5676 log_error("Invalid environment block");
5680 esc
= shell_maybe_quote(sep
+ 1, ESCAPE_POSIX
);
5684 printf("%.*s=%s\n", (int)(sep
-s
), s
, esc
);
5688 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5689 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5690 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5695 r
= acquire_bus(BUS_MANAGER
, &bus
);
5699 pager_open(arg_no_pager
, false);
5701 r
= sd_bus_get_property(
5703 "org.freedesktop.systemd1",
5704 "/org/freedesktop/systemd1",
5705 "org.freedesktop.systemd1.Manager",
5711 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5713 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5715 return bus_log_parse_error(r
);
5717 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0) {
5718 r
= print_variable(text
);
5723 return bus_log_parse_error(r
);
5725 r
= sd_bus_message_exit_container(reply
);
5727 return bus_log_parse_error(r
);
5732 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5733 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5734 _cleanup_free_
char *cmdline_init
= NULL
;
5735 const char *root
, *init
;
5739 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5740 log_error("Cannot switch root remotely.");
5744 if (argc
< 2 || argc
> 3) {
5745 log_error("Wrong number of arguments.");
5754 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5755 "init", &cmdline_init
,
5758 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5760 init
= cmdline_init
;
5763 init
= empty_to_null(init
);
5765 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5767 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5768 root_init_path
= strjoina(root
, "/", init
);
5770 /* If the passed init is actually the same as the
5771 * systemd binary, then let's suppress it. */
5772 if (files_same(root_init_path
, root_systemd_path
, 0) > 0)
5776 /* Instruct PID1 to exclude us from its killing spree applied during
5777 * the transition. Otherwise we would exit with a failure status even
5778 * though the switch to the new root has succeed. */
5779 argv_cmdline
[0] = '@';
5781 r
= acquire_bus(BUS_MANAGER
, &bus
);
5785 /* If we are slow to exit after the root switch, the new systemd instance
5786 * will send us a signal to terminate. Just ignore it and exit normally.
5787 * This way the unit does not end up as failed.
5789 r
= ignore_signals(SIGTERM
, -1);
5791 log_warning_errno(r
, "Failed to change disposition of SIGTERM to ignore: %m");
5793 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5795 r
= sd_bus_call_method(
5797 "org.freedesktop.systemd1",
5798 "/org/freedesktop/systemd1",
5799 "org.freedesktop.systemd1.Manager",
5805 (void) default_signals(SIGTERM
, -1);
5807 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5813 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5814 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5815 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5823 r
= acquire_bus(BUS_MANAGER
, &bus
);
5827 polkit_agent_open_if_enabled();
5829 method
= streq(argv
[0], "set-environment")
5831 : "UnsetEnvironment";
5833 r
= sd_bus_message_new_method_call(
5836 "org.freedesktop.systemd1",
5837 "/org/freedesktop/systemd1",
5838 "org.freedesktop.systemd1.Manager",
5841 return bus_log_create_error(r
);
5843 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5845 return bus_log_create_error(r
);
5847 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5849 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5854 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5855 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5856 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5860 r
= acquire_bus(BUS_MANAGER
, &bus
);
5864 polkit_agent_open_if_enabled();
5866 r
= sd_bus_message_new_method_call(
5869 "org.freedesktop.systemd1",
5870 "/org/freedesktop/systemd1",
5871 "org.freedesktop.systemd1.Manager",
5874 return bus_log_create_error(r
);
5877 r
= sd_bus_message_append_strv(m
, environ
);
5881 r
= sd_bus_message_open_container(m
, 'a', "s");
5883 return bus_log_create_error(r
);
5885 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5887 if (!env_name_is_valid(*a
)) {
5888 log_error("Not a valid environment variable name: %s", *a
);
5892 STRV_FOREACH(b
, environ
) {
5895 eq
= startswith(*b
, *a
);
5896 if (eq
&& *eq
== '=') {
5898 r
= sd_bus_message_append(m
, "s", *b
);
5900 return bus_log_create_error(r
);
5907 r
= sd_bus_message_close_container(m
);
5910 return bus_log_create_error(r
);
5912 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5914 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5919 static int enable_sysv_units(const char *verb
, char **args
) {
5922 #if HAVE_SYSV_COMPAT
5923 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5926 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5928 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5931 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5934 if (!STR_IN_SET(verb
,
5940 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5947 const char *argv
[] = {
5948 ROOTLIBEXECDIR
"/systemd-sysv-install",
5955 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5956 bool found_native
= false, found_sysv
;
5965 if (!endswith(name
, ".service"))
5968 if (path_is_absolute(name
))
5971 j
= unit_file_exists(arg_scope
, &paths
, name
);
5972 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5973 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5974 found_native
= j
!= 0;
5976 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5977 * prefer the native unit */
5978 if (found_native
&& streq(verb
, "is-enabled"))
5981 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5985 p
[strlen(p
) - strlen(".service")] = 0;
5986 found_sysv
= access(p
, F_OK
) >= 0;
5992 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5994 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5997 if (!isempty(arg_root
))
5998 argv
[c
++] = q
= strappend("--root=", arg_root
);
6001 argv
[c
++] = basename(p
);
6004 l
= strv_join((char**)argv
, " ");
6009 log_info("Executing: %s", l
);
6013 return log_error_errno(errno
, "Failed to fork: %m");
6014 else if (pid
== 0) {
6017 (void) reset_all_signal_handlers();
6018 (void) reset_signal_mask();
6020 execv(argv
[0], (char**) argv
);
6021 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
6022 _exit(EXIT_FAILURE
);
6025 j
= wait_for_terminate(pid
, &status
);
6027 return log_error_errno(j
, "Failed to wait for child: %m");
6029 if (status
.si_code
== CLD_EXITED
) {
6030 if (streq(verb
, "is-enabled")) {
6031 if (status
.si_status
== 0) {
6040 } else if (status
.si_status
!= 0)
6041 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
6043 log_error("Unexpected waitid() result.");
6050 /* Remove this entry, so that we don't try enabling it as native unit */
6053 assert(args
[f
] == name
);
6054 strv_remove(args
, name
);
6061 static int mangle_names(char **original_names
, char ***mangled_names
) {
6062 char **i
, **l
, **name
;
6065 l
= i
= new(char*, strv_length(original_names
) + 1);
6069 STRV_FOREACH(name
, original_names
) {
6071 /* When enabling units qualified path names are OK,
6072 * too, hence allow them explicitly. */
6074 if (is_path(*name
)) {
6081 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
6085 return log_error_errno(r
, "Failed to mangle unit name: %m");
6098 static int normalize_filenames(char **names
) {
6102 STRV_FOREACH(u
, names
)
6103 if (!path_is_absolute(*u
)) {
6104 char* normalized_path
;
6106 if (!isempty(arg_root
)) {
6107 log_error("Non-absolute paths are not allowed when --root is used: %s", *u
);
6111 if (!strchr(*u
,'/')) {
6112 log_error("Link argument does contain at least one directory separator: %s", *u
);
6116 r
= path_make_absolute_cwd(*u
, &normalized_path
);
6120 free_and_replace(*u
, normalized_path
);
6126 static int normalize_names(char **names
, bool warn_if_path
) {
6128 bool was_path
= false;
6130 STRV_FOREACH(u
, names
) {
6136 r
= free_and_strdup(u
, basename(*u
));
6138 return log_error_errno(r
, "Failed to normalize unit file path: %m");
6143 if (warn_if_path
&& was_path
)
6144 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
6149 static int unit_exists(LookupPaths
*lp
, const char *unit
) {
6150 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6151 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6152 _cleanup_free_
char *path
= NULL
;
6153 static const struct bus_properties_map property_map
[] = {
6154 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
6155 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
)},
6158 UnitStatusInfo info
= {};
6162 if (unit_name_is_valid(unit
, UNIT_NAME_TEMPLATE
))
6163 return unit_find_template_path(unit
, lp
, NULL
, NULL
);
6165 path
= unit_dbus_path_from_name(unit
);
6169 r
= acquire_bus(BUS_MANAGER
, &bus
);
6173 r
= sd_bus_call_method(
6175 "org.freedesktop.systemd1",
6177 "org.freedesktop.DBus.Properties",
6183 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
6185 r
= bus_message_map_all_properties(reply
, property_map
, &error
, &info
);
6187 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
6189 return !streq_ptr(info
.load_state
, "not-found") || !streq_ptr(info
.active_state
, "inactive");
6192 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
6193 _cleanup_strv_free_
char **names
= NULL
;
6194 const char *verb
= argv
[0];
6195 UnitFileChange
*changes
= NULL
;
6196 unsigned n_changes
= 0;
6197 int carries_install_info
= -1;
6198 bool ignore_carries_install_info
= arg_quiet
;
6204 r
= mangle_names(strv_skip(argv
, 1), &names
);
6208 r
= enable_sysv_units(verb
, names
);
6212 /* If the operation was fully executed by the SysV compat, let's finish early */
6213 if (strv_isempty(names
)) {
6214 if (arg_no_reload
|| install_client_side())
6216 return daemon_reload(argc
, argv
, userdata
);
6219 if (streq(verb
, "disable")) {
6220 r
= normalize_names(names
, true);
6225 if (streq(verb
, "link")) {
6226 r
= normalize_filenames(names
);
6231 if (install_client_side()) {
6232 UnitFileFlags flags
;
6234 flags
= args_to_flags();
6235 if (streq(verb
, "enable")) {
6236 r
= unit_file_enable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6237 carries_install_info
= r
;
6238 } else if (streq(verb
, "disable"))
6239 r
= unit_file_disable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6240 else if (streq(verb
, "reenable")) {
6241 r
= unit_file_reenable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6242 carries_install_info
= r
;
6243 } else if (streq(verb
, "link"))
6244 r
= unit_file_link(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6245 else if (streq(verb
, "preset")) {
6246 r
= unit_file_preset(arg_scope
, flags
, arg_root
, names
, arg_preset_mode
, &changes
, &n_changes
);
6247 } else if (streq(verb
, "mask"))
6248 r
= unit_file_mask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6249 else if (streq(verb
, "unmask"))
6250 r
= unit_file_unmask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6251 else if (streq(verb
, "revert"))
6252 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
6254 assert_not_reached("Unknown verb");
6256 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
6261 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6262 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6263 bool expect_carries_install_info
= false;
6264 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
6268 if (STR_IN_SET(verb
, "mask", "unmask")) {
6270 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6272 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6276 STRV_FOREACH(name
, names
) {
6277 r
= unit_exists(&lp
, *name
);
6281 log_notice("Unit %s does not exist, proceeding anyway.", *names
);
6285 r
= acquire_bus(BUS_MANAGER
, &bus
);
6289 polkit_agent_open_if_enabled();
6291 if (streq(verb
, "enable")) {
6292 method
= "EnableUnitFiles";
6293 expect_carries_install_info
= true;
6294 } else if (streq(verb
, "disable")) {
6295 method
= "DisableUnitFiles";
6297 } else if (streq(verb
, "reenable")) {
6298 method
= "ReenableUnitFiles";
6299 expect_carries_install_info
= true;
6300 } else if (streq(verb
, "link"))
6301 method
= "LinkUnitFiles";
6302 else if (streq(verb
, "preset")) {
6304 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
6305 method
= "PresetUnitFilesWithMode";
6306 send_preset_mode
= true;
6308 method
= "PresetUnitFiles";
6310 expect_carries_install_info
= true;
6311 ignore_carries_install_info
= true;
6312 } else if (streq(verb
, "mask"))
6313 method
= "MaskUnitFiles";
6314 else if (streq(verb
, "unmask")) {
6315 method
= "UnmaskUnitFiles";
6317 } else if (streq(verb
, "revert")) {
6318 method
= "RevertUnitFiles";
6319 send_runtime
= send_force
= false;
6321 assert_not_reached("Unknown verb");
6323 r
= sd_bus_message_new_method_call(
6326 "org.freedesktop.systemd1",
6327 "/org/freedesktop/systemd1",
6328 "org.freedesktop.systemd1.Manager",
6331 return bus_log_create_error(r
);
6333 r
= sd_bus_message_append_strv(m
, names
);
6335 return bus_log_create_error(r
);
6337 if (send_preset_mode
) {
6338 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
6340 return bus_log_create_error(r
);
6344 r
= sd_bus_message_append(m
, "b", arg_runtime
);
6346 return bus_log_create_error(r
);
6350 r
= sd_bus_message_append(m
, "b", arg_force
);
6352 return bus_log_create_error(r
);
6355 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6357 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
6359 if (expect_carries_install_info
) {
6360 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
6362 return bus_log_parse_error(r
);
6365 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6369 /* Try to reload if enabled */
6371 r
= daemon_reload(argc
, argv
, userdata
);
6376 if (carries_install_info
== 0 && !ignore_carries_install_info
)
6377 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6378 "settings in the [Install] section, and DefaultInstance for template units).\n"
6379 "This means they are not meant to be enabled using systemctl.\n"
6380 "Possible reasons for having this kind of units are:\n"
6381 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6382 " .wants/ or .requires/ directory.\n"
6383 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6384 " a requirement dependency on it.\n"
6385 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6386 " D-Bus, udev, scripted systemctl call, ...).\n"
6387 "4) In case of template units, the unit is meant to be enabled with some\n"
6388 " instance name specified.");
6390 if (arg_now
&& STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
6394 r
= acquire_bus(BUS_MANAGER
, &bus
);
6398 len
= strv_length(names
);
6400 char *new_args
[len
+ 2];
6402 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
6403 for (i
= 0; i
< len
; i
++)
6404 new_args
[i
+ 1] = basename(names
[i
]);
6405 new_args
[i
+ 1] = NULL
;
6407 r
= start_unit(len
+ 1, new_args
, userdata
);
6412 unit_file_changes_free(changes
, n_changes
);
6417 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
6418 _cleanup_strv_free_
char **names
= NULL
;
6419 _cleanup_free_
char *target
= NULL
;
6420 const char *verb
= argv
[0];
6421 UnitFileChange
*changes
= NULL
;
6422 unsigned n_changes
= 0;
6429 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
6431 return log_error_errno(r
, "Failed to mangle unit name: %m");
6433 r
= mangle_names(strv_skip(argv
, 2), &names
);
6437 if (streq(verb
, "add-wants"))
6439 else if (streq(verb
, "add-requires"))
6440 dep
= UNIT_REQUIRES
;
6442 assert_not_reached("Unknown verb");
6444 if (install_client_side()) {
6445 r
= unit_file_add_dependency(arg_scope
, args_to_flags(), arg_root
, names
, target
, dep
, &changes
, &n_changes
);
6446 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
6451 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6452 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6455 r
= acquire_bus(BUS_MANAGER
, &bus
);
6459 polkit_agent_open_if_enabled();
6461 r
= sd_bus_message_new_method_call(
6464 "org.freedesktop.systemd1",
6465 "/org/freedesktop/systemd1",
6466 "org.freedesktop.systemd1.Manager",
6467 "AddDependencyUnitFiles");
6469 return bus_log_create_error(r
);
6471 r
= sd_bus_message_append_strv(m
, names
);
6473 return bus_log_create_error(r
);
6475 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
6477 return bus_log_create_error(r
);
6479 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6481 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
6483 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6487 if (arg_no_reload
) {
6492 r
= daemon_reload(argc
, argv
, userdata
);
6496 unit_file_changes_free(changes
, n_changes
);
6501 static int preset_all(int argc
, char *argv
[], void *userdata
) {
6502 UnitFileChange
*changes
= NULL
;
6503 unsigned n_changes
= 0;
6506 if (install_client_side()) {
6507 r
= unit_file_preset_all(arg_scope
, args_to_flags(), arg_root
, arg_preset_mode
, &changes
, &n_changes
);
6508 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
6513 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6514 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6517 r
= acquire_bus(BUS_MANAGER
, &bus
);
6521 polkit_agent_open_if_enabled();
6523 r
= sd_bus_call_method(
6525 "org.freedesktop.systemd1",
6526 "/org/freedesktop/systemd1",
6527 "org.freedesktop.systemd1.Manager",
6528 "PresetAllUnitFiles",
6532 unit_file_preset_mode_to_string(arg_preset_mode
),
6536 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
6538 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6542 if (arg_no_reload
) {
6547 r
= daemon_reload(argc
, argv
, userdata
);
6551 unit_file_changes_free(changes
, n_changes
);
6556 static int show_installation_targets_client_side(const char *name
) {
6557 UnitFileChange
*changes
= NULL
;
6558 unsigned n_changes
= 0, i
;
6559 UnitFileFlags flags
;
6563 p
= STRV_MAKE(name
);
6564 flags
= UNIT_FILE_DRY_RUN
|
6565 (arg_runtime
? UNIT_FILE_RUNTIME
: 0);
6567 r
= unit_file_disable(UNIT_FILE_SYSTEM
, flags
, NULL
, p
, &changes
, &n_changes
);
6569 return log_error_errno(r
, "Failed to get file links for %s: %m", name
);
6571 for (i
= 0; i
< n_changes
; i
++)
6572 if (changes
[i
].type
== UNIT_FILE_UNLINK
)
6573 printf(" %s\n", changes
[i
].path
);
6578 static int show_installation_targets(sd_bus
*bus
, const char *name
) {
6579 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6580 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6584 r
= sd_bus_call_method(
6586 "org.freedesktop.systemd1",
6587 "/org/freedesktop/systemd1",
6588 "org.freedesktop.systemd1.Manager",
6592 "sb", name
, arg_runtime
);
6594 return log_error_errno(r
, "Failed to get unit file links for %s: %s", name
, bus_error_message(&error
, r
));
6596 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
6598 return bus_log_parse_error(r
);
6600 while ((r
= sd_bus_message_read(reply
, "s", &link
)) > 0)
6601 printf(" %s\n", link
);
6604 return bus_log_parse_error(r
);
6606 r
= sd_bus_message_exit_container(reply
);
6608 return bus_log_parse_error(r
);
6613 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
6615 _cleanup_strv_free_
char **names
= NULL
;
6620 r
= mangle_names(strv_skip(argv
, 1), &names
);
6624 r
= enable_sysv_units(argv
[0], names
);
6630 if (install_client_side()) {
6631 STRV_FOREACH(name
, names
) {
6632 UnitFileState state
;
6634 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
6636 return log_error_errno(r
, "Failed to get unit file state for %s: %m", *name
);
6640 UNIT_FILE_ENABLED_RUNTIME
,
6643 UNIT_FILE_GENERATED
))
6647 puts(unit_file_state_to_string(state
));
6649 r
= show_installation_targets_client_side(*name
);
6658 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6661 r
= acquire_bus(BUS_MANAGER
, &bus
);
6665 STRV_FOREACH(name
, names
) {
6666 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6669 r
= sd_bus_call_method(
6671 "org.freedesktop.systemd1",
6672 "/org/freedesktop/systemd1",
6673 "org.freedesktop.systemd1.Manager",
6679 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
6681 r
= sd_bus_message_read(reply
, "s", &s
);
6683 return bus_log_parse_error(r
);
6685 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6691 r
= show_installation_targets(bus
, *name
);
6699 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
6702 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
6703 _cleanup_free_
char *state
= NULL
;
6707 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
6710 return EXIT_FAILURE
;
6713 r
= acquire_bus(BUS_MANAGER
, &bus
);
6717 r
= sd_bus_get_property_string(
6719 "org.freedesktop.systemd1",
6720 "/org/freedesktop/systemd1",
6721 "org.freedesktop.systemd1.Manager",
6734 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
6737 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
6738 _cleanup_free_
char *t
= NULL
;
6742 assert(original_path
);
6745 r
= tempfn_random(new_path
, NULL
, &t
);
6747 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
6749 r
= mkdir_parents(new_path
, 0755);
6751 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
6753 r
= copy_file(original_path
, t
, 0, 0644, 0, COPY_REFLINK
);
6758 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
6761 return log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", new_path
);
6769 static int get_file_to_edit(
6770 const LookupPaths
*paths
,
6774 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
6779 path
= strjoin(paths
->persistent_config
, "/", name
);
6784 run
= strjoin(paths
->runtime_config
, "/", name
);
6790 if (access(path
, F_OK
) >= 0) {
6791 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
6805 static int unit_file_create_new(
6806 const LookupPaths
*paths
,
6807 const char *unit_name
,
6809 char **ret_new_path
,
6810 char **ret_tmp_path
) {
6812 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6816 assert(ret_new_path
);
6817 assert(ret_tmp_path
);
6819 ending
= strjoina(unit_name
, suffix
);
6820 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
6824 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6830 *ret_new_path
= tmp_new_path
;
6831 *ret_tmp_path
= tmp_tmp_path
;
6836 static int unit_file_create_copy(
6837 const LookupPaths
*paths
,
6838 const char *unit_name
,
6839 const char *fragment_path
,
6840 char **ret_new_path
,
6841 char **ret_tmp_path
) {
6843 char *tmp_new_path
, *tmp_tmp_path
;
6846 assert(fragment_path
);
6848 assert(ret_new_path
);
6849 assert(ret_tmp_path
);
6851 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6855 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6858 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6863 if (response
!= 'y') {
6864 log_warning("%s ignored", unit_name
);
6866 return -EKEYREJECTED
;
6870 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6876 *ret_new_path
= tmp_new_path
;
6877 *ret_tmp_path
= tmp_tmp_path
;
6882 static int run_editor(char **paths
) {
6890 return log_error_errno(errno
, "Failed to fork: %m");
6894 char *editor
, **editor_args
= NULL
;
6895 char **tmp_path
, **original_path
, *p
;
6896 unsigned n_editor_args
= 0, i
= 1;
6899 (void) reset_all_signal_handlers();
6900 (void) reset_signal_mask();
6902 argc
= strv_length(paths
)/2 + 1;
6904 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6905 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6906 * we try to execute well known editors
6908 editor
= getenv("SYSTEMD_EDITOR");
6910 editor
= getenv("EDITOR");
6912 editor
= getenv("VISUAL");
6914 if (!isempty(editor
)) {
6915 editor_args
= strv_split(editor
, WHITESPACE
);
6918 _exit(EXIT_FAILURE
);
6920 n_editor_args
= strv_length(editor_args
);
6921 argc
+= n_editor_args
- 1;
6923 args
= newa(const char*, argc
+ 1);
6925 if (n_editor_args
> 0) {
6926 args
[0] = editor_args
[0];
6927 for (; i
< n_editor_args
; i
++)
6928 args
[i
] = editor_args
[i
];
6931 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6932 args
[i
] = *tmp_path
;
6937 if (n_editor_args
> 0)
6938 execvp(args
[0], (char* const*) args
);
6940 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6942 execvp(p
, (char* const*) args
);
6943 /* We do not fail if the editor doesn't exist
6944 * because we want to try each one of them before
6947 if (errno
!= ENOENT
) {
6948 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6949 _exit(EXIT_FAILURE
);
6953 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6954 _exit(EXIT_FAILURE
);
6957 r
= wait_for_terminate_and_warn("editor", pid
, true);
6959 return log_error_errno(r
, "Failed to wait for child: %m");
6964 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6965 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6972 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6976 STRV_FOREACH(name
, names
) {
6977 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
, *tmp_name
= NULL
;
6978 const char *unit_name
;
6980 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6988 log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
6989 arg_scope
== UNIT_FILE_GLOBAL
? " --global" :
6990 arg_scope
== UNIT_FILE_USER
? " --user" : "",
6995 /* Create a new unit from scratch */
6997 r
= unit_file_create_new(&lp
, unit_name
,
6998 arg_full
? NULL
: ".d/override.conf",
6999 &new_path
, &tmp_path
);
7003 unit_name
= basename(path
);
7004 /* We follow unit aliases, but we need to propagate the instance */
7005 if (unit_name_is_valid(*name
, UNIT_NAME_INSTANCE
) &&
7006 unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
7007 _cleanup_free_
char *instance
= NULL
;
7009 r
= unit_name_to_instance(*name
, &instance
);
7013 r
= unit_name_replace_instance(unit_name
, instance
, &tmp_name
);
7017 unit_name
= tmp_name
;
7021 r
= unit_file_create_copy(&lp
, unit_name
, path
, &new_path
, &tmp_path
);
7023 r
= unit_file_create_new(&lp
, unit_name
, ".d/override.conf", &new_path
, &tmp_path
);
7028 r
= strv_push_pair(paths
, new_path
, tmp_path
);
7031 new_path
= tmp_path
= NULL
;
7037 static int edit(int argc
, char *argv
[], void *userdata
) {
7038 _cleanup_strv_free_
char **names
= NULL
;
7039 _cleanup_strv_free_
char **paths
= NULL
;
7040 char **original
, **tmp
;
7045 log_error("Cannot edit units if not on a tty.");
7049 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
7050 log_error("Cannot edit units remotely.");
7054 r
= acquire_bus(BUS_MANAGER
, &bus
);
7058 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
7060 return log_error_errno(r
, "Failed to expand names: %m");
7062 r
= find_paths_to_edit(bus
, names
, &paths
);
7066 if (strv_isempty(paths
))
7069 r
= run_editor(paths
);
7073 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
7074 /* If the temporary file is empty we ignore it. It's
7075 * useful if the user wants to cancel its modification
7077 if (null_or_empty_path(*tmp
)) {
7078 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
7082 r
= rename(*tmp
, *original
);
7084 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
7091 if (!arg_no_reload
&& !install_client_side())
7092 r
= daemon_reload(argc
, argv
, userdata
);
7095 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
7096 (void) unlink(*tmp
);
7098 /* Removing empty dropin dirs */
7100 _cleanup_free_
char *dir
;
7102 dir
= dirname_malloc(*original
);
7106 /* no need to check if the dir is empty, rmdir
7107 * does nothing if it is not the case.
7116 static void systemctl_help(void) {
7118 pager_open(arg_no_pager
, false);
7120 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
7121 "Query or send control commands to the systemd manager.\n\n"
7122 " -h --help Show this help\n"
7123 " --version Show package version\n"
7124 " --system Connect to system manager\n"
7125 " --user Connect to user service manager\n"
7126 " -H --host=[USER@]HOST\n"
7127 " Operate on remote host\n"
7128 " -M --machine=CONTAINER\n"
7129 " Operate on local container\n"
7130 " -t --type=TYPE List units of a particular type\n"
7131 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
7132 " -p --property=NAME Show only properties by this name\n"
7133 " -a --all Show all properties/all units currently in memory,\n"
7134 " including dead/empty ones. To list all units installed on\n"
7135 " the system, use the 'list-unit-files' command instead.\n"
7136 " --failed Same as --state=failed\n"
7137 " -l --full Don't ellipsize unit names on output\n"
7138 " -r --recursive Show unit list of host and local containers\n"
7139 " --reverse Show reverse dependencies with 'list-dependencies'\n"
7140 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
7141 " queueing a new job\n"
7142 " --show-types When showing sockets, explicitly show their type\n"
7143 " --value When showing properties, only print the value\n"
7144 " -i --ignore-inhibitors\n"
7145 " When shutting down or sleeping, ignore inhibitors\n"
7146 " --kill-who=WHO Who to send signal to\n"
7147 " -s --signal=SIGNAL Which signal to send\n"
7148 " --now Start or stop unit in addition to enabling or disabling it\n"
7149 " -q --quiet Suppress output\n"
7150 " --wait For (re)start, wait until service stopped again\n"
7151 " --no-block Do not wait until operation finished\n"
7152 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7153 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
7154 " --no-legend Do not print a legend (column headers and hints)\n"
7155 " --no-pager Do not pipe output into a pager\n"
7156 " --no-ask-password\n"
7157 " Do not ask for system passwords\n"
7158 " --global Enable/disable/mask unit files globally\n"
7159 " --runtime Enable/disable/mask unit files temporarily until next\n"
7161 " -f --force When enabling unit files, override existing symlinks\n"
7162 " When shutting down, execute action immediately\n"
7163 " --preset-mode= Apply only enable, only disable, or all presets\n"
7164 " --root=PATH Enable/disable/mask unit files in the specified root\n"
7166 " -n --lines=INTEGER Number of journal entries to show\n"
7167 " -o --output=STRING Change journal output mode (short, short-precise,\n"
7168 " short-iso, short-iso-precise, short-full,\n"
7169 " short-monotonic, short-unix,\n"
7170 " verbose, export, json, json-pretty, json-sse, cat)\n"
7171 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
7172 " --plain Print unit dependencies as a list instead of a tree\n\n"
7174 " list-units [PATTERN...] List units currently in memory\n"
7175 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
7177 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
7179 " start NAME... Start (activate) one or more units\n"
7180 " stop NAME... Stop (deactivate) one or more units\n"
7181 " reload NAME... Reload one or more units\n"
7182 " restart NAME... Start or restart one or more units\n"
7183 " try-restart NAME... Restart one or more units if active\n"
7184 " reload-or-restart NAME... Reload one or more units if possible,\n"
7185 " otherwise start or restart\n"
7186 " try-reload-or-restart NAME... If active, reload one or more units,\n"
7187 " if supported, otherwise restart\n"
7188 " isolate NAME Start one unit and stop all others\n"
7189 " kill NAME... Send signal to processes of a unit\n"
7190 " is-active PATTERN... Check whether units are active\n"
7191 " is-failed PATTERN... Check whether units are failed\n"
7192 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
7193 " show [PATTERN...|JOB...] Show properties of one or more\n"
7194 " units/jobs or the manager\n"
7195 " cat PATTERN... Show files and drop-ins of one or more units\n"
7196 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
7197 " help PATTERN...|PID... Show manual for one or more units\n"
7198 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
7200 " list-dependencies [NAME] Recursively show units which are required\n"
7201 " or wanted by this unit or by which this\n"
7202 " unit is required or wanted\n\n"
7203 "Unit File Commands:\n"
7204 " list-unit-files [PATTERN...] List installed unit files\n"
7205 " enable [NAME...|PATH...] Enable one or more unit files\n"
7206 " disable NAME... Disable one or more unit files\n"
7207 " reenable NAME... Reenable one or more unit files\n"
7208 " preset NAME... Enable/disable one or more unit files\n"
7209 " based on preset configuration\n"
7210 " preset-all Enable/disable all unit files based on\n"
7211 " preset configuration\n"
7212 " is-enabled NAME... Check whether unit files are enabled\n"
7213 " mask NAME... Mask one or more units\n"
7214 " unmask NAME... Unmask one or more units\n"
7215 " link PATH... Link one or more units files into\n"
7216 " the search path\n"
7217 " revert NAME... Revert one or more unit files to vendor\n"
7219 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
7220 " on specified one or more units\n"
7221 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
7222 " on specified one or more units\n"
7223 " edit NAME... Edit one or more unit files\n"
7224 " get-default Get the name of the default target\n"
7225 " set-default NAME Set the default target\n\n"
7226 "Machine Commands:\n"
7227 " list-machines [PATTERN...] List local containers and host\n\n"
7229 " list-jobs [PATTERN...] List jobs\n"
7230 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
7231 "Environment Commands:\n"
7232 " show-environment Dump environment\n"
7233 " set-environment NAME=VALUE... Set one or more environment variables\n"
7234 " unset-environment NAME... Unset one or more environment variables\n"
7235 " import-environment [NAME...] Import all or some environment variables\n\n"
7236 "Manager Lifecycle Commands:\n"
7237 " daemon-reload Reload systemd manager configuration\n"
7238 " daemon-reexec Reexecute systemd manager\n\n"
7239 "System Commands:\n"
7240 " is-system-running Check whether system is fully running\n"
7241 " default Enter system default mode\n"
7242 " rescue Enter system rescue mode\n"
7243 " emergency Enter system emergency mode\n"
7244 " halt Shut down and halt the system\n"
7245 " poweroff Shut down and power-off the system\n"
7246 " reboot [ARG] Shut down and reboot the system\n"
7247 " kexec Shut down and reboot the system with kexec\n"
7248 " exit [EXIT_CODE] Request user instance or container exit\n"
7249 " switch-root ROOT [INIT] Change to a different root file system\n"
7250 " suspend Suspend the system\n"
7251 " hibernate Hibernate the system\n"
7252 " hybrid-sleep Hibernate and suspend the system\n",
7253 program_invocation_short_name
);
7256 static void halt_help(void) {
7257 printf("%s [OPTIONS...]%s\n\n"
7258 "%s the system.\n\n"
7259 " --help Show this help\n"
7260 " --halt Halt the machine\n"
7261 " -p --poweroff Switch off the machine\n"
7262 " --reboot Reboot the machine\n"
7263 " -f --force Force immediate halt/power-off/reboot\n"
7264 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
7265 " -d --no-wtmp Don't write wtmp record\n"
7266 " --no-wall Don't send wall message before halt/power-off/reboot\n",
7267 program_invocation_short_name
,
7268 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
7269 arg_action
== ACTION_REBOOT
? "Reboot" :
7270 arg_action
== ACTION_POWEROFF
? "Power off" :
7274 static void shutdown_help(void) {
7275 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
7276 "Shut down the system.\n\n"
7277 " --help Show this help\n"
7278 " -H --halt Halt the machine\n"
7279 " -P --poweroff Power-off the machine\n"
7280 " -r --reboot Reboot the machine\n"
7281 " -h Equivalent to --poweroff, overridden by --halt\n"
7282 " -k Don't halt/power-off/reboot, just send warnings\n"
7283 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7284 " -c Cancel a pending shutdown\n",
7285 program_invocation_short_name
);
7288 static void telinit_help(void) {
7289 printf("%s [OPTIONS...] {COMMAND}\n\n"
7290 "Send control commands to the init daemon.\n\n"
7291 " --help Show this help\n"
7292 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7294 " 0 Power-off the machine\n"
7295 " 6 Reboot the machine\n"
7296 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7297 " 1, s, S Enter rescue mode\n"
7298 " q, Q Reload init daemon configuration\n"
7299 " u, U Reexecute init daemon\n",
7300 program_invocation_short_name
);
7303 static void runlevel_help(void) {
7304 printf("%s [OPTIONS...]\n\n"
7305 "Prints the previous and current runlevel of the init system.\n\n"
7306 " --help Show this help\n",
7307 program_invocation_short_name
);
7310 static void help_types(void) {
7314 puts("Available unit types:");
7315 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
7316 puts(unit_type_to_string(i
));
7319 static void help_states(void) {
7323 puts("Available unit load states:");
7324 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
7325 puts(unit_load_state_to_string(i
));
7328 puts("\nAvailable unit active states:");
7329 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
7330 puts(unit_active_state_to_string(i
));
7333 puts("\nAvailable automount unit substates:");
7334 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
7335 puts(automount_state_to_string(i
));
7338 puts("\nAvailable device unit substates:");
7339 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
7340 puts(device_state_to_string(i
));
7343 puts("\nAvailable mount unit substates:");
7344 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
7345 puts(mount_state_to_string(i
));
7348 puts("\nAvailable path unit substates:");
7349 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
7350 puts(path_state_to_string(i
));
7353 puts("\nAvailable scope unit substates:");
7354 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
7355 puts(scope_state_to_string(i
));
7358 puts("\nAvailable service unit substates:");
7359 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
7360 puts(service_state_to_string(i
));
7363 puts("\nAvailable slice unit substates:");
7364 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
7365 puts(slice_state_to_string(i
));
7368 puts("\nAvailable socket unit substates:");
7369 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
7370 puts(socket_state_to_string(i
));
7373 puts("\nAvailable swap unit substates:");
7374 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
7375 puts(swap_state_to_string(i
));
7378 puts("\nAvailable target unit substates:");
7379 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
7380 puts(target_state_to_string(i
));
7383 puts("\nAvailable timer unit substates:");
7384 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
7385 puts(timer_state_to_string(i
));
7388 static int systemctl_parse_argv(int argc
, char *argv
[]) {
7397 ARG_IGNORE_DEPENDENCIES
,
7410 ARG_NO_ASK_PASSWORD
,
7424 static const struct option options
[] = {
7425 { "help", no_argument
, NULL
, 'h' },
7426 { "version", no_argument
, NULL
, ARG_VERSION
},
7427 { "type", required_argument
, NULL
, 't' },
7428 { "property", required_argument
, NULL
, 'p' },
7429 { "all", no_argument
, NULL
, 'a' },
7430 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
7431 { "after", no_argument
, NULL
, ARG_AFTER
},
7432 { "before", no_argument
, NULL
, ARG_BEFORE
},
7433 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
7434 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
7435 { "full", no_argument
, NULL
, 'l' },
7436 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
7437 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
7438 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
7439 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
7440 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
7441 { "value", no_argument
, NULL
, ARG_VALUE
},
7442 { "user", no_argument
, NULL
, ARG_USER
},
7443 { "system", no_argument
, NULL
, ARG_SYSTEM
},
7444 { "global", no_argument
, NULL
, ARG_GLOBAL
},
7445 { "wait", no_argument
, NULL
, ARG_WAIT
},
7446 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
7447 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
7448 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
7449 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7450 { "quiet", no_argument
, NULL
, 'q' },
7451 { "root", required_argument
, NULL
, ARG_ROOT
},
7452 { "force", no_argument
, NULL
, ARG_FORCE
},
7453 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
7454 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
7455 { "signal", required_argument
, NULL
, 's' },
7456 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
7457 { "host", required_argument
, NULL
, 'H' },
7458 { "machine", required_argument
, NULL
, 'M' },
7459 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
7460 { "lines", required_argument
, NULL
, 'n' },
7461 { "output", required_argument
, NULL
, 'o' },
7462 { "plain", no_argument
, NULL
, ARG_PLAIN
},
7463 { "state", required_argument
, NULL
, ARG_STATE
},
7464 { "recursive", no_argument
, NULL
, 'r' },
7465 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
7466 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
7467 { "now", no_argument
, NULL
, ARG_NOW
},
7468 { "message", required_argument
, NULL
, ARG_MESSAGE
},
7478 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7479 arg_ask_password
= true;
7481 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
7493 if (isempty(optarg
)) {
7494 log_error("--type= requires arguments.");
7498 for (p
= optarg
;;) {
7499 _cleanup_free_
char *type
= NULL
;
7501 r
= extract_first_word(&p
, &type
, ",", 0);
7503 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
7507 if (streq(type
, "help")) {
7512 if (unit_type_from_string(type
) >= 0) {
7513 if (strv_push(&arg_types
, type
) < 0)
7519 /* It's much nicer to use --state= for
7520 * load states, but let's support this
7521 * in --types= too for compatibility
7522 * with old versions */
7523 if (unit_load_state_from_string(type
) >= 0) {
7524 if (strv_push(&arg_states
, type
) < 0)
7530 log_error("Unknown unit type or load state '%s'.", type
);
7531 log_info("Use -t help to see a list of allowed values.");
7539 /* Make sure that if the empty property list
7540 was specified, we won't show any properties. */
7541 if (isempty(optarg
) && !arg_properties
) {
7542 arg_properties
= new0(char*, 1);
7543 if (!arg_properties
)
7546 for (p
= optarg
;;) {
7547 _cleanup_free_
char *prop
= NULL
;
7549 r
= extract_first_word(&p
, &prop
, ",", 0);
7551 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
7555 if (strv_push(&arg_properties
, prop
) < 0)
7561 /* If the user asked for a particular
7562 * property, show it to him, even if it is
7574 arg_dependency
= DEPENDENCY_REVERSE
;
7578 arg_dependency
= DEPENDENCY_AFTER
;
7579 arg_jobs_after
= true;
7583 arg_dependency
= DEPENDENCY_BEFORE
;
7584 arg_jobs_before
= true;
7587 case ARG_SHOW_TYPES
:
7588 arg_show_types
= true;
7596 arg_job_mode
= optarg
;
7600 arg_job_mode
= "fail";
7603 case ARG_IRREVERSIBLE
:
7604 arg_job_mode
= "replace-irreversibly";
7607 case ARG_IGNORE_DEPENDENCIES
:
7608 arg_job_mode
= "ignore-dependencies";
7612 arg_scope
= UNIT_FILE_USER
;
7616 arg_scope
= UNIT_FILE_SYSTEM
;
7620 arg_scope
= UNIT_FILE_GLOBAL
;
7628 arg_no_block
= true;
7632 arg_no_legend
= true;
7636 arg_no_pager
= true;
7644 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
7654 if (strv_extend(&arg_states
, "failed") < 0)
7672 arg_no_reload
= true;
7676 arg_kill_who
= optarg
;
7680 arg_signal
= signal_from_string_try_harder(optarg
);
7681 if (arg_signal
< 0) {
7682 log_error("Failed to parse signal string %s.", optarg
);
7687 case ARG_NO_ASK_PASSWORD
:
7688 arg_ask_password
= false;
7692 arg_transport
= BUS_TRANSPORT_REMOTE
;
7697 arg_transport
= BUS_TRANSPORT_MACHINE
;
7706 if (safe_atou(optarg
, &arg_lines
) < 0) {
7707 log_error("Failed to parse lines '%s'", optarg
);
7713 arg_output
= output_mode_from_string(optarg
);
7714 if (arg_output
< 0) {
7715 log_error("Unknown output '%s'.", optarg
);
7721 arg_ignore_inhibitors
= true;
7728 case ARG_FIRMWARE_SETUP
:
7729 arg_firmware_setup
= true;
7733 if (isempty(optarg
)) {
7734 log_error("--state= requires arguments.");
7738 for (p
= optarg
;;) {
7739 _cleanup_free_
char *s
= NULL
;
7741 r
= extract_first_word(&p
, &s
, ",", 0);
7743 return log_error_errno(r
, "Failed to parse state: %s", optarg
);
7747 if (streq(s
, "help")) {
7752 if (strv_push(&arg_states
, s
) < 0)
7761 if (geteuid() != 0) {
7762 log_error("--recursive requires root privileges.");
7766 arg_recursive
= true;
7769 case ARG_PRESET_MODE
:
7771 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
7772 if (arg_preset_mode
< 0) {
7773 log_error("Failed to parse preset mode: %s.", optarg
);
7784 if (strv_extend(&arg_wall
, optarg
) < 0)
7792 assert_not_reached("Unhandled option");
7795 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
7796 log_error("Cannot access user instance remotely.");
7800 if (arg_wait
&& arg_no_block
) {
7801 log_error("--wait may not be combined with --no-block.");
7808 static int halt_parse_argv(int argc
, char *argv
[]) {
7817 static const struct option options
[] = {
7818 { "help", no_argument
, NULL
, ARG_HELP
},
7819 { "halt", no_argument
, NULL
, ARG_HALT
},
7820 { "poweroff", no_argument
, NULL
, 'p' },
7821 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
7822 { "force", no_argument
, NULL
, 'f' },
7823 { "wtmp-only", no_argument
, NULL
, 'w' },
7824 { "no-wtmp", no_argument
, NULL
, 'd' },
7825 { "no-sync", no_argument
, NULL
, 'n' },
7826 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7835 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
7836 if (IN_SET(runlevel
, '0', '6'))
7839 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
7847 arg_action
= ACTION_HALT
;
7851 if (arg_action
!= ACTION_REBOOT
)
7852 arg_action
= ACTION_POWEROFF
;
7856 arg_action
= ACTION_REBOOT
;
7881 /* Compatibility nops */
7888 assert_not_reached("Unhandled option");
7891 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7892 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7895 } else if (optind
< argc
) {
7896 log_error("Too many arguments.");
7903 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7907 if (streq(t
, "now"))
7909 else if (!strchr(t
, ':')) {
7912 if (safe_atou64(t
, &u
) < 0)
7915 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7924 hour
= strtol(t
, &e
, 10);
7925 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7928 minute
= strtol(e
+1, &e
, 10);
7929 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7932 n
= now(CLOCK_REALTIME
);
7933 s
= (time_t) (n
/ USEC_PER_SEC
);
7935 assert_se(localtime_r(&s
, &tm
));
7937 tm
.tm_hour
= (int) hour
;
7938 tm
.tm_min
= (int) minute
;
7941 assert_se(s
= mktime(&tm
));
7943 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7946 *_u
+= USEC_PER_DAY
;
7952 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7959 static const struct option options
[] = {
7960 { "help", no_argument
, NULL
, ARG_HELP
},
7961 { "halt", no_argument
, NULL
, 'H' },
7962 { "poweroff", no_argument
, NULL
, 'P' },
7963 { "reboot", no_argument
, NULL
, 'r' },
7964 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7965 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7975 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7983 arg_action
= ACTION_HALT
;
7987 arg_action
= ACTION_POWEROFF
;
7992 arg_action
= ACTION_KEXEC
;
7994 arg_action
= ACTION_REBOOT
;
7998 arg_action
= ACTION_KEXEC
;
8002 if (arg_action
!= ACTION_HALT
)
8003 arg_action
= ACTION_POWEROFF
;
8018 /* Compatibility nops */
8022 arg_action
= ACTION_CANCEL_SHUTDOWN
;
8029 assert_not_reached("Unhandled option");
8032 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
8033 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
8035 log_error("Failed to parse time specification: %s", argv
[optind
]);
8039 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
8041 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
8042 /* No time argument for shutdown cancel */
8043 wall
= argv
+ optind
;
8044 else if (argc
> optind
+ 1)
8045 /* We skip the time argument */
8046 wall
= argv
+ optind
+ 1;
8049 arg_wall
= strv_copy(wall
);
8059 static int telinit_parse_argv(int argc
, char *argv
[]) {
8066 static const struct option options
[] = {
8067 { "help", no_argument
, NULL
, ARG_HELP
},
8068 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
8072 static const struct {
8076 { '0', ACTION_POWEROFF
},
8077 { '6', ACTION_REBOOT
},
8078 { '1', ACTION_RESCUE
},
8079 { '2', ACTION_RUNLEVEL2
},
8080 { '3', ACTION_RUNLEVEL3
},
8081 { '4', ACTION_RUNLEVEL4
},
8082 { '5', ACTION_RUNLEVEL5
},
8083 { 's', ACTION_RESCUE
},
8084 { 'S', ACTION_RESCUE
},
8085 { 'q', ACTION_RELOAD
},
8086 { 'Q', ACTION_RELOAD
},
8087 { 'u', ACTION_REEXEC
},
8088 { 'U', ACTION_REEXEC
}
8097 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
8112 assert_not_reached("Unhandled option");
8115 if (optind
>= argc
) {
8116 log_error("%s: required argument missing.", program_invocation_short_name
);
8120 if (optind
+ 1 < argc
) {
8121 log_error("Too many arguments.");
8125 if (strlen(argv
[optind
]) != 1) {
8126 log_error("Expected single character argument.");
8130 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
8131 if (table
[i
].from
== argv
[optind
][0])
8134 if (i
>= ELEMENTSOF(table
)) {
8135 log_error("Unknown command '%s'.", argv
[optind
]);
8139 arg_action
= table
[i
].to
;
8146 static int runlevel_parse_argv(int argc
, char *argv
[]) {
8152 static const struct option options
[] = {
8153 { "help", no_argument
, NULL
, ARG_HELP
},
8162 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
8173 assert_not_reached("Unhandled option");
8176 if (optind
< argc
) {
8177 log_error("Too many arguments.");
8184 static int parse_argv(int argc
, char *argv
[]) {
8188 if (program_invocation_short_name
) {
8190 if (strstr(program_invocation_short_name
, "halt")) {
8191 arg_action
= ACTION_HALT
;
8192 return halt_parse_argv(argc
, argv
);
8193 } else if (strstr(program_invocation_short_name
, "poweroff")) {
8194 arg_action
= ACTION_POWEROFF
;
8195 return halt_parse_argv(argc
, argv
);
8196 } else if (strstr(program_invocation_short_name
, "reboot")) {
8198 arg_action
= ACTION_KEXEC
;
8200 arg_action
= ACTION_REBOOT
;
8201 return halt_parse_argv(argc
, argv
);
8202 } else if (strstr(program_invocation_short_name
, "shutdown")) {
8203 arg_action
= ACTION_POWEROFF
;
8204 return shutdown_parse_argv(argc
, argv
);
8205 } else if (strstr(program_invocation_short_name
, "init")) {
8207 if (sd_booted() > 0) {
8208 arg_action
= _ACTION_INVALID
;
8209 return telinit_parse_argv(argc
, argv
);
8211 /* Hmm, so some other init system is
8212 * running, we need to forward this
8213 * request to it. For now we simply
8214 * guess that it is Upstart. */
8216 execv(TELINIT
, argv
);
8218 log_error("Couldn't find an alternative telinit implementation to spawn.");
8222 } else if (strstr(program_invocation_short_name
, "runlevel")) {
8223 arg_action
= ACTION_RUNLEVEL
;
8224 return runlevel_parse_argv(argc
, argv
);
8228 arg_action
= ACTION_SYSTEMCTL
;
8229 return systemctl_parse_argv(argc
, argv
);
8232 #if HAVE_SYSV_COMPAT
8233 _pure_
static int action_to_runlevel(void) {
8235 static const char table
[_ACTION_MAX
] = {
8236 [ACTION_HALT
] = '0',
8237 [ACTION_POWEROFF
] = '0',
8238 [ACTION_REBOOT
] = '6',
8239 [ACTION_RUNLEVEL2
] = '2',
8240 [ACTION_RUNLEVEL3
] = '3',
8241 [ACTION_RUNLEVEL4
] = '4',
8242 [ACTION_RUNLEVEL5
] = '5',
8243 [ACTION_RESCUE
] = '1'
8246 assert(arg_action
>= 0 && arg_action
< _ACTION_MAX
);
8248 return table
[arg_action
];
8252 static int talk_initctl(void) {
8253 #if HAVE_SYSV_COMPAT
8254 struct init_request request
= {
8255 .magic
= INIT_MAGIC
,
8257 .cmd
= INIT_CMD_RUNLVL
8260 _cleanup_close_
int fd
= -1;
8264 rl
= action_to_runlevel();
8268 request
.runlevel
= rl
;
8270 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
8272 if (errno
== ENOENT
)
8275 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
8278 r
= loop_write(fd
, &request
, sizeof(request
), false);
8280 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
8288 static int systemctl_main(int argc
, char *argv
[]) {
8290 static const Verb verbs
[] = {
8291 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
8292 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
8293 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
8294 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
8295 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
8296 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
8297 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, trivial_method
},
8298 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
8299 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8300 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8301 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8302 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8303 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8304 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8305 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8306 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
8307 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8308 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
8309 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8310 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
8311 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
8312 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
8313 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8314 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8315 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
8316 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8317 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
8318 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8319 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8320 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8321 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8322 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
8323 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8324 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8325 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
8326 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8327 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8328 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_system_special
},
8329 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8330 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8331 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8332 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8333 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
8334 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8335 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8336 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
8337 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
8338 { "enable", 2, VERB_ANY
, 0, enable_unit
},
8339 { "disable", 2, VERB_ANY
, 0, enable_unit
},
8340 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
8341 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
8342 { "preset", 2, VERB_ANY
, 0, enable_unit
},
8343 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
8344 { "mask", 2, VERB_ANY
, 0, enable_unit
},
8345 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
8346 { "link", 2, VERB_ANY
, 0, enable_unit
},
8347 { "revert", 2, VERB_ANY
, 0, enable_unit
},
8348 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
8349 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
8350 { "set-default", 2, 2, 0, set_default
},
8351 { "get-default", VERB_ANY
, 1, 0, get_default
},
8352 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
8353 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
8354 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
8355 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
8356 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
8360 return dispatch_verb(argc
, argv
, verbs
, NULL
);
8363 static int reload_with_fallback(void) {
8365 /* First, try systemd via D-Bus. */
8366 if (daemon_reload(0, NULL
, NULL
) >= 0)
8369 /* Nothing else worked, so let's try signals */
8370 assert(IN_SET(arg_action
, ACTION_RELOAD
, ACTION_REEXEC
));
8372 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
8373 return log_error_errno(errno
, "kill() failed: %m");
8378 static int start_with_fallback(void) {
8380 /* First, try systemd via D-Bus. */
8381 if (start_unit(0, NULL
, NULL
) >= 0)
8384 /* Nothing else worked, so let's try /dev/initctl */
8385 if (talk_initctl() > 0)
8388 log_error("Failed to talk to init daemon.");
8392 static int halt_now(enum action a
) {
8395 /* The kernel will automaticall flush ATA disks and suchlike
8396 * on reboot(), but the file systems need to be synce'd
8397 * explicitly in advance. */
8401 /* Make sure C-A-D is handled by the kernel from this point
8403 (void) reboot(RB_ENABLE_CAD
);
8409 log_info("Halting.");
8410 (void) reboot(RB_HALT_SYSTEM
);
8413 case ACTION_POWEROFF
:
8415 log_info("Powering off.");
8416 (void) reboot(RB_POWER_OFF
);
8420 case ACTION_REBOOT
: {
8421 _cleanup_free_
char *param
= NULL
;
8423 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
8424 if (r
< 0 && r
!= -ENOENT
)
8425 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
8427 if (!isempty(param
)) {
8429 log_info("Rebooting with argument '%s'.", param
);
8430 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
8431 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
8435 log_info("Rebooting.");
8436 (void) reboot(RB_AUTOBOOT
);
8441 assert_not_reached("Unknown action.");
8445 static int logind_schedule_shutdown(void) {
8448 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8449 char date
[FORMAT_TIMESTAMP_MAX
];
8454 r
= acquire_bus(BUS_FULL
, &bus
);
8458 switch (arg_action
) {
8462 case ACTION_POWEROFF
:
8463 action
= "poweroff";
8478 action
= strjoina("dry-", action
);
8480 (void) logind_set_wall_message();
8482 r
= sd_bus_call_method(
8484 "org.freedesktop.login1",
8485 "/org/freedesktop/login1",
8486 "org.freedesktop.login1.Manager",
8494 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
8497 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
8500 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8505 static int halt_main(void) {
8508 r
= logind_check_inhibitors(arg_action
);
8513 return logind_schedule_shutdown();
8515 if (geteuid() != 0) {
8516 if (arg_dry
|| arg_force
> 0) {
8517 log_error("Must be root.");
8521 /* Try logind if we are a normal user and no special
8522 * mode applies. Maybe PolicyKit allows us to shutdown
8524 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
, ACTION_HALT
)) {
8525 r
= logind_reboot(arg_action
);
8528 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
8529 /* requested operation is not
8530 * supported on the local system or
8531 * already in progress */
8533 /* on all other errors, try low-level operation */
8537 if (!arg_dry
&& !arg_force
)
8538 return start_with_fallback();
8540 assert(geteuid() == 0);
8543 if (sd_booted() > 0)
8544 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8546 r
= utmp_put_shutdown();
8548 log_warning_errno(r
, "Failed to write utmp record: %m");
8555 r
= halt_now(arg_action
);
8556 return log_error_errno(r
, "Failed to reboot: %m");
8559 static int runlevel_main(void) {
8560 int r
, runlevel
, previous
;
8562 r
= utmp_get_runlevel(&runlevel
, &previous
);
8569 previous
<= 0 ? 'N' : previous
,
8570 runlevel
<= 0 ? 'N' : runlevel
);
8575 static int logind_cancel_shutdown(void) {
8577 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8581 r
= acquire_bus(BUS_FULL
, &bus
);
8585 (void) logind_set_wall_message();
8587 r
= sd_bus_call_method(
8589 "org.freedesktop.login1",
8590 "/org/freedesktop/login1",
8591 "org.freedesktop.login1.Manager",
8592 "CancelScheduledShutdown",
8596 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
8600 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8605 int main(int argc
, char*argv
[]) {
8608 argv_cmdline
= argv
[0];
8610 setlocale(LC_ALL
, "");
8611 log_parse_environment();
8615 /* Explicitly not on_tty() to avoid setting cached value.
8616 * This becomes relevant for piping output which might be
8618 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
8620 r
= parse_argv(argc
, argv
);
8624 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
8627 log_info("Running in chroot, ignoring request.");
8632 /* systemctl_main() will print an error message for the bus
8633 * connection, but only if it needs to */
8635 switch (arg_action
) {
8637 case ACTION_SYSTEMCTL
:
8638 r
= systemctl_main(argc
, argv
);
8641 /* Legacy command aliases set arg_action. They provide some fallbacks,
8642 * e.g. to tell sysvinit to reboot after you have installed systemd
8646 case ACTION_POWEROFF
:
8652 case ACTION_RUNLEVEL2
:
8653 case ACTION_RUNLEVEL3
:
8654 case ACTION_RUNLEVEL4
:
8655 case ACTION_RUNLEVEL5
:
8657 r
= start_with_fallback();
8662 r
= reload_with_fallback();
8665 case ACTION_CANCEL_SHUTDOWN
:
8666 r
= logind_cancel_shutdown();
8669 case ACTION_RUNLEVEL
:
8670 r
= runlevel_main();
8674 case ACTION_SUSPEND
:
8675 case ACTION_HIBERNATE
:
8676 case ACTION_HYBRID_SLEEP
:
8677 case ACTION_EMERGENCY
:
8678 case ACTION_DEFAULT
:
8679 /* systemctl verbs with no equivalent in the legacy commands.
8680 * These cannot appear in arg_action. Fall through. */
8682 case _ACTION_INVALID
:
8684 assert_not_reached("Unknown action");
8691 ask_password_agent_close();
8692 polkit_agent_close();
8694 strv_free(arg_types
);
8695 strv_free(arg_states
);
8696 strv_free(arg_properties
);
8698 strv_free(arg_wall
);
8701 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8702 return r
< 0 ? EXIT_FAILURE
: r
;