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_maybe(void) {
272 /* Open the polkit agent as a child process if necessary */
274 if (arg_scope
!= UNIT_FILE_SYSTEM
)
277 polkit_agent_open_if_enabled(arg_transport
, arg_ask_password
);
280 static OutputFlags
get_output_flags(void) {
282 arg_all
* OUTPUT_SHOW_ALL
|
283 arg_full
* OUTPUT_FULL_WIDTH
|
284 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
285 colors_enabled() * OUTPUT_COLOR
|
286 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
289 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
292 if (!sd_bus_error_is_set(error
))
295 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
296 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
297 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
298 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
299 return EXIT_NOPERMISSION
;
301 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
302 return EXIT_NOTINSTALLED
;
304 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
305 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
306 return EXIT_NOTIMPLEMENTED
;
308 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
309 return EXIT_NOTCONFIGURED
;
317 static bool install_client_side(void) {
319 /* Decides when to execute enable/disable/... operations
320 * client-side rather than server-side. */
322 if (running_in_chroot() > 0)
325 if (sd_booted() <= 0)
328 if (!isempty(arg_root
))
331 if (arg_scope
== UNIT_FILE_GLOBAL
)
334 /* Unsupported environment variable, mostly for debugging purposes */
335 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
341 static int compare_unit_info(const void *a
, const void *b
) {
342 const UnitInfo
*u
= a
, *v
= b
;
346 /* First, order by machine */
347 if (!u
->machine
&& v
->machine
)
349 if (u
->machine
&& !v
->machine
)
351 if (u
->machine
&& v
->machine
) {
352 r
= strcasecmp(u
->machine
, v
->machine
);
357 /* Second, order by unit type */
358 d1
= strrchr(u
->id
, '.');
359 d2
= strrchr(v
->id
, '.');
361 r
= strcasecmp(d1
, d2
);
366 /* Third, order by name */
367 return strcasecmp(u
->id
, v
->id
);
370 static const char* unit_type_suffix(const char *name
) {
373 dot
= strrchr(name
, '.');
380 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
383 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
386 if (arg_types
&& !strv_find(arg_types
, unit_type_suffix(u
->id
)))
392 /* Note that '--all' is not purely a state filter, but also a
393 * filter that hides units that "follow" other units (which is
394 * used for device units that appear under different names). */
395 if (!isempty(u
->following
))
398 if (!strv_isempty(arg_states
))
401 /* By default show all units except the ones in inactive
402 * state and with no pending job */
406 if (streq(u
->active_state
, "inactive"))
412 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
413 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
, max_desc_len
;
415 unsigned n_shown
= 0;
418 max_id_len
= strlen("UNIT");
419 load_len
= strlen("LOAD");
420 active_len
= strlen("ACTIVE");
421 sub_len
= strlen("SUB");
422 job_len
= strlen("JOB");
423 max_desc_len
= strlen("DESCRIPTION");
425 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
426 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
427 load_len
= MAX(load_len
, strlen(u
->load_state
));
428 active_len
= MAX(active_len
, strlen(u
->active_state
));
429 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
430 max_desc_len
= MAX(max_desc_len
, strlen(u
->description
));
432 if (u
->job_id
!= 0) {
433 job_len
= MAX(job_len
, strlen(u
->job_type
));
437 if (!arg_no_legend
&&
438 (streq(u
->active_state
, "failed") ||
439 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
443 if (!arg_full
&& original_stdout_is_tty
) {
446 id_len
= MIN(max_id_len
, 25u); /* as much as it needs, but at most 25 for now */
447 basic_len
= circle_len
+ 1 + id_len
+ 1 + load_len
+ 1 + active_len
+ 1 + sub_len
+ 1;
450 basic_len
+= job_len
+ 1;
452 if (basic_len
< (unsigned) columns()) {
453 unsigned extra_len
, incr
;
454 extra_len
= columns() - basic_len
;
456 /* Either UNIT already got 25, or is fully satisfied.
457 * Grant up to 25 to DESC now. */
458 incr
= MIN(extra_len
, 25u);
462 /* Of the remainder give as much as the ID needs to the ID, and give the rest to the
463 * description but not more than it needs. */
465 incr
= MIN(max_id_len
- id_len
, extra_len
);
467 desc_len
+= MIN(extra_len
- incr
, max_desc_len
- desc_len
);
473 desc_len
= max_desc_len
;
476 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
477 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
478 const char *on_underline
= "", *off_underline
= "";
479 const char *on_loaded
= "", *off_loaded
= "";
480 const char *on_active
= "", *off_active
= "";
481 const char *on_circle
= "", *off_circle
= "";
483 bool circle
= false, underline
= false;
485 if (!n_shown
&& !arg_no_legend
) {
490 printf("%s%-*s %-*s %-*s %-*s ",
494 active_len
, "ACTIVE",
498 printf("%-*s ", job_len
, "JOB");
502 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
509 if (u
+ 1 < unit_infos
+ c
&&
510 !streq(unit_type_suffix(u
->id
), unit_type_suffix((u
+ 1)->id
))) {
511 on_underline
= ansi_underline();
512 off_underline
= ansi_normal();
516 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
517 on_circle
= ansi_highlight_yellow();
518 off_circle
= ansi_normal();
520 on_loaded
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
521 off_loaded
= underline
? on_underline
: ansi_normal();
522 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
523 on_circle
= ansi_highlight_red();
524 off_circle
= ansi_normal();
526 on_active
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
527 off_active
= underline
? on_underline
: ansi_normal();
531 j
= strjoin(u
->machine
, ":", u
->id
);
540 e
= ellipsize(id
, id_len
, 33);
548 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
550 printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
552 on_active
, id_len
, id
, off_active
,
553 on_loaded
, load_len
, u
->load_state
, off_loaded
,
554 on_active
, active_len
, u
->active_state
,
555 sub_len
, u
->sub_state
, off_active
,
556 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
560 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
565 if (!arg_no_legend
) {
566 const char *on
, *off
;
570 "LOAD = Reflects whether the unit definition was properly loaded.\n"
571 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
572 "SUB = The low-level unit activation state, values depend on unit type.");
573 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
574 on
= ansi_highlight();
577 on
= ansi_highlight_red();
582 printf("%s%u loaded units listed.%s\n"
583 "To show all installed unit files use 'systemctl list-unit-files'.\n",
586 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
587 "To show all installed unit files use 'systemctl list-unit-files'.\n",
594 static int get_unit_list(
598 UnitInfo
**unit_infos
,
600 sd_bus_message
**_reply
) {
602 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
603 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
604 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
608 bool fallback
= false;
614 r
= sd_bus_message_new_method_call(
617 "org.freedesktop.systemd1",
618 "/org/freedesktop/systemd1",
619 "org.freedesktop.systemd1.Manager",
620 "ListUnitsByPatterns");
622 return bus_log_create_error(r
);
624 r
= sd_bus_message_append_strv(m
, arg_states
);
626 return bus_log_create_error(r
);
628 r
= sd_bus_message_append_strv(m
, patterns
);
630 return bus_log_create_error(r
);
632 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
633 if (r
< 0 && (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
) ||
634 sd_bus_error_has_name(&error
, SD_BUS_ERROR_ACCESS_DENIED
))) {
635 /* Fallback to legacy ListUnitsFiltered method */
637 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
638 m
= sd_bus_message_unref(m
);
639 sd_bus_error_free(&error
);
641 r
= sd_bus_message_new_method_call(
644 "org.freedesktop.systemd1",
645 "/org/freedesktop/systemd1",
646 "org.freedesktop.systemd1.Manager",
647 "ListUnitsFiltered");
649 return bus_log_create_error(r
);
651 r
= sd_bus_message_append_strv(m
, arg_states
);
653 return bus_log_create_error(r
);
655 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
658 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
660 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
662 return bus_log_parse_error(r
);
664 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
667 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
670 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
673 (*unit_infos
)[c
++] = u
;
676 return bus_log_parse_error(r
);
678 r
= sd_bus_message_exit_container(reply
);
680 return bus_log_parse_error(r
);
688 static void message_set_freep(Set
**set
) {
691 while ((m
= set_steal_first(*set
)))
692 sd_bus_message_unref(m
);
697 static int get_unit_list_recursive(
700 UnitInfo
**_unit_infos
,
704 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
705 _cleanup_(message_set_freep
) Set
*replies
;
706 sd_bus_message
*reply
;
714 replies
= set_new(NULL
);
718 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
722 r
= set_put(replies
, reply
);
724 sd_bus_message_unref(reply
);
729 _cleanup_strv_free_
char **machines
= NULL
;
732 r
= sd_get_machine_names(&machines
);
734 return log_error_errno(r
, "Failed to get machine names: %m");
736 STRV_FOREACH(i
, machines
) {
737 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
740 r
= sd_bus_open_system_machine(&container
, *i
);
742 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
746 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
752 r
= set_put(replies
, reply
);
754 sd_bus_message_unref(reply
);
759 *_machines
= machines
;
764 *_unit_infos
= unit_infos
;
773 static int list_units(int argc
, char *argv
[], void *userdata
) {
774 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
775 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
776 _cleanup_strv_free_
char **machines
= NULL
;
780 r
= acquire_bus(BUS_MANAGER
, &bus
);
784 pager_open(arg_no_pager
, false);
786 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
790 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
791 return output_units_list(unit_infos
, r
);
794 static int get_triggered_units(
799 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
806 r
= sd_bus_get_property_strv(
808 "org.freedesktop.systemd1",
810 "org.freedesktop.systemd1.Unit",
815 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
820 static int get_listening(
822 const char* unit_path
,
825 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
826 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
827 const char *type
, *path
;
830 r
= sd_bus_get_property(
832 "org.freedesktop.systemd1",
834 "org.freedesktop.systemd1.Socket",
840 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
842 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
844 return bus_log_parse_error(r
);
846 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
848 r
= strv_extend(listening
, type
);
852 r
= strv_extend(listening
, path
);
859 return bus_log_parse_error(r
);
861 r
= sd_bus_message_exit_container(reply
);
863 return bus_log_parse_error(r
);
875 /* Note: triggered is a list here, although it almost certainly
876 * will always be one unit. Nevertheless, dbus API allows for multiple
877 * values, so let's follow that. */
880 /* The strv above is shared. free is set only in the first one. */
884 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
890 if (!a
->machine
&& b
->machine
)
892 if (a
->machine
&& !b
->machine
)
894 if (a
->machine
&& b
->machine
) {
895 o
= strcasecmp(a
->machine
, b
->machine
);
900 o
= strcmp(a
->path
, b
->path
);
902 o
= strcmp(a
->type
, b
->type
);
907 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
908 struct socket_info
*s
;
909 unsigned pathlen
= strlen("LISTEN"),
910 typelen
= strlen("TYPE") * arg_show_types
,
911 socklen
= strlen("UNIT"),
912 servlen
= strlen("ACTIVATES");
913 const char *on
, *off
;
915 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
919 socklen
= MAX(socklen
, strlen(s
->id
));
921 typelen
= MAX(typelen
, strlen(s
->type
));
922 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
924 STRV_FOREACH(a
, s
->triggered
)
925 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
926 servlen
= MAX(servlen
, tmp
);
931 printf("%-*s %-*.*s%-*s %s\n",
933 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
937 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
938 _cleanup_free_
char *j
= NULL
;
943 j
= strjoin(s
->machine
, ":", s
->path
);
951 printf("%-*s %-*s %-*s",
952 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
955 pathlen
, path
, socklen
, s
->id
);
956 STRV_FOREACH(a
, s
->triggered
)
958 a
== s
->triggered
? "" : ",", *a
);
962 on
= ansi_highlight();
967 on
= ansi_highlight_red();
971 if (!arg_no_legend
) {
972 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
974 printf("Pass --all to see loaded but inactive sockets, too.\n");
980 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
981 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
982 _cleanup_strv_free_
char **machines
= NULL
;
983 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
984 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
986 struct socket_info
*s
;
992 r
= acquire_bus(BUS_MANAGER
, &bus
);
996 pager_open(arg_no_pager
, false);
998 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1002 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1003 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
1006 if (!endswith(u
->id
, ".socket"))
1009 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1013 c
= get_listening(bus
, u
->unit_path
, &listening
);
1019 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
1024 for (i
= 0; i
< c
; i
++)
1025 socket_infos
[cs
+ i
] = (struct socket_info
) {
1026 .machine
= u
->machine
,
1028 .type
= listening
[i
*2],
1029 .path
= listening
[i
*2 + 1],
1030 .triggered
= triggered
,
1031 .own_triggered
= i
==0,
1034 /* from this point on we will cleanup those socket_infos */
1037 listening
= triggered
= NULL
; /* avoid cleanup */
1040 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
1041 (__compar_fn_t
) socket_info_compare
);
1043 output_sockets_list(socket_infos
, cs
);
1046 assert(cs
== 0 || socket_infos
);
1047 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
1050 if (s
->own_triggered
)
1051 strv_free(s
->triggered
);
1057 static int get_next_elapse(
1060 dual_timestamp
*next
) {
1062 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1070 r
= sd_bus_get_property_trivial(
1072 "org.freedesktop.systemd1",
1074 "org.freedesktop.systemd1.Timer",
1075 "NextElapseUSecMonotonic",
1080 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1082 r
= sd_bus_get_property_trivial(
1084 "org.freedesktop.systemd1",
1086 "org.freedesktop.systemd1.Timer",
1087 "NextElapseUSecRealtime",
1092 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1098 static int get_last_trigger(
1103 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1110 r
= sd_bus_get_property_trivial(
1112 "org.freedesktop.systemd1",
1114 "org.freedesktop.systemd1.Timer",
1120 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1126 const char* machine
;
1129 usec_t last_trigger
;
1133 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1139 if (!a
->machine
&& b
->machine
)
1141 if (a
->machine
&& !b
->machine
)
1143 if (a
->machine
&& b
->machine
) {
1144 o
= strcasecmp(a
->machine
, b
->machine
);
1149 if (a
->next_elapse
< b
->next_elapse
)
1151 if (a
->next_elapse
> b
->next_elapse
)
1154 return strcmp(a
->id
, b
->id
);
1157 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1158 struct timer_info
*t
;
1160 nextlen
= strlen("NEXT"),
1161 leftlen
= strlen("LEFT"),
1162 lastlen
= strlen("LAST"),
1163 passedlen
= strlen("PASSED"),
1164 unitlen
= strlen("UNIT"),
1165 activatelen
= strlen("ACTIVATES");
1167 const char *on
, *off
;
1169 assert(timer_infos
|| n
== 0);
1171 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1175 if (t
->next_elapse
> 0) {
1176 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1178 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1179 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1181 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1182 leftlen
= MAX(leftlen
, strlen(trel
));
1185 if (t
->last_trigger
> 0) {
1186 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1188 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1189 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1191 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1192 passedlen
= MAX(passedlen
, strlen(trel
));
1195 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1197 STRV_FOREACH(a
, t
->triggered
)
1198 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1200 activatelen
= MAX(activatelen
, ul
);
1205 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1209 passedlen
, "PASSED",
1213 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1214 _cleanup_free_
char *j
= NULL
;
1216 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1217 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1220 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1221 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1223 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1224 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1227 j
= strjoin(t
->machine
, ":", t
->id
);
1234 printf("%-*s %-*s %-*s %-*s %-*s",
1235 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1237 STRV_FOREACH(a
, t
->triggered
)
1239 a
== t
->triggered
? "" : ",", *a
);
1243 on
= ansi_highlight();
1244 off
= ansi_normal();
1248 on
= ansi_highlight_red();
1249 off
= ansi_normal();
1252 if (!arg_no_legend
) {
1253 printf("%s%u timers listed.%s\n", on
, n
, off
);
1255 printf("Pass --all to see loaded but inactive timers, too.\n");
1261 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1267 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1270 if (next
->monotonic
> nw
->monotonic
)
1271 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1273 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1275 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1276 next_elapse
= MIN(converted
, next
->realtime
);
1278 next_elapse
= converted
;
1281 next_elapse
= next
->realtime
;
1286 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1287 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1288 _cleanup_strv_free_
char **machines
= NULL
;
1289 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1290 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1291 struct timer_info
*t
;
1299 r
= acquire_bus(BUS_MANAGER
, &bus
);
1303 pager_open(arg_no_pager
, false);
1305 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1309 dual_timestamp_get(&nw
);
1311 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1312 _cleanup_strv_free_
char **triggered
= NULL
;
1313 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1316 if (!endswith(u
->id
, ".timer"))
1319 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1323 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1327 get_last_trigger(bus
, u
->unit_path
, &last
);
1329 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1334 m
= calc_next_elapse(&nw
, &next
);
1336 timer_infos
[c
++] = (struct timer_info
) {
1337 .machine
= u
->machine
,
1340 .last_trigger
= last
,
1341 .triggered
= triggered
,
1344 triggered
= NULL
; /* avoid cleanup */
1347 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1348 (__compar_fn_t
) timer_info_compare
);
1350 output_timers_list(timer_infos
, c
);
1353 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1354 strv_free(t
->triggered
);
1359 static int compare_unit_file_list(const void *a
, const void *b
) {
1360 const char *d1
, *d2
;
1361 const UnitFileList
*u
= a
, *v
= b
;
1363 d1
= strrchr(u
->path
, '.');
1364 d2
= strrchr(v
->path
, '.');
1369 r
= strcasecmp(d1
, d2
);
1374 return strcasecmp(basename(u
->path
), basename(v
->path
));
1377 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1380 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1383 if (!strv_isempty(arg_types
)) {
1386 dot
= strrchr(u
->path
, '.');
1390 if (!strv_find(arg_types
, dot
+1))
1394 if (!strv_isempty(states
) &&
1395 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1401 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1402 unsigned max_id_len
, id_cols
, state_cols
;
1403 const UnitFileList
*u
;
1405 max_id_len
= strlen("UNIT FILE");
1406 state_cols
= strlen("STATE");
1408 for (u
= units
; u
< units
+ c
; u
++) {
1409 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1410 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1414 unsigned basic_cols
;
1416 id_cols
= MIN(max_id_len
, 25u);
1417 basic_cols
= 1 + id_cols
+ state_cols
;
1418 if (basic_cols
< (unsigned) columns())
1419 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1421 id_cols
= max_id_len
;
1423 if (!arg_no_legend
&& c
> 0)
1424 printf("%s%-*s %-*s%s\n",
1426 id_cols
, "UNIT FILE",
1427 state_cols
, "STATE",
1430 for (u
= units
; u
< units
+ c
; u
++) {
1431 const char *on_underline
= NULL
, *on_color
= NULL
, *off
= NULL
, *id
;
1432 _cleanup_free_
char *e
= NULL
;
1435 underline
= u
+ 1 < units
+ c
&&
1436 !streq(unit_type_suffix(u
->path
), unit_type_suffix((u
+ 1)->path
));
1439 on_underline
= ansi_underline();
1441 if (IN_SET(u
->state
,
1443 UNIT_FILE_MASKED_RUNTIME
,
1446 on_color
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
1447 else if (u
->state
== UNIT_FILE_ENABLED
)
1448 on_color
= underline
? ansi_highlight_green_underline() : ansi_highlight_green();
1450 if (on_underline
|| on_color
)
1451 off
= ansi_normal();
1453 id
= basename(u
->path
);
1455 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1457 printf("%s%-*s %s%-*s%s\n",
1458 strempty(on_underline
),
1459 id_cols
, e
? e
: id
,
1460 strempty(on_color
), state_cols
, unit_file_state_to_string(u
->state
), strempty(off
));
1464 printf("\n%u unit files listed.\n", c
);
1467 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1468 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1469 _cleanup_free_ UnitFileList
*units
= NULL
;
1476 bool fallback
= false;
1478 if (install_client_side()) {
1484 h
= hashmap_new(&string_hash_ops
);
1488 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1490 unit_file_list_free(h
);
1491 return log_error_errno(r
, "Failed to get unit file list: %m");
1494 n_units
= hashmap_size(h
);
1496 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1498 unit_file_list_free(h
);
1502 HASHMAP_FOREACH(u
, h
, i
) {
1503 if (!output_show_unit_file(u
, NULL
, NULL
))
1510 assert(c
<= n_units
);
1515 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1516 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1519 r
= acquire_bus(BUS_MANAGER
, &bus
);
1523 r
= sd_bus_message_new_method_call(
1526 "org.freedesktop.systemd1",
1527 "/org/freedesktop/systemd1",
1528 "org.freedesktop.systemd1.Manager",
1529 "ListUnitFilesByPatterns");
1531 return bus_log_create_error(r
);
1533 r
= sd_bus_message_append_strv(m
, arg_states
);
1535 return bus_log_create_error(r
);
1537 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1539 return bus_log_create_error(r
);
1541 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1542 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1543 /* Fallback to legacy ListUnitFiles method */
1545 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1546 m
= sd_bus_message_unref(m
);
1547 sd_bus_error_free(&error
);
1549 r
= sd_bus_message_new_method_call(
1552 "org.freedesktop.systemd1",
1553 "/org/freedesktop/systemd1",
1554 "org.freedesktop.systemd1.Manager",
1557 return bus_log_create_error(r
);
1559 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1562 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1564 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1566 return bus_log_parse_error(r
);
1568 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1570 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1573 units
[c
] = (struct UnitFileList
) {
1575 unit_file_state_from_string(state
)
1578 if (output_show_unit_file(&units
[c
],
1579 fallback
? arg_states
: NULL
,
1580 fallback
? strv_skip(argv
, 1) : NULL
))
1585 return bus_log_parse_error(r
);
1587 r
= sd_bus_message_exit_container(reply
);
1589 return bus_log_parse_error(r
);
1592 pager_open(arg_no_pager
, false);
1594 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1595 output_unit_file_list(units
, c
);
1597 if (install_client_side())
1598 for (unit
= units
; unit
< units
+ c
; unit
++)
1604 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1605 _cleanup_free_
char *n
= NULL
;
1606 size_t max_len
= MAX(columns(),20u);
1612 for (i
= level
- 1; i
>= 0; i
--) {
1614 if (len
> max_len
- 3 && !arg_full
) {
1615 printf("%s...\n",max_len
% 2 ? "" : " ");
1618 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1622 if (len
> max_len
- 3 && !arg_full
) {
1623 printf("%s...\n",max_len
% 2 ? "" : " ");
1627 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1631 printf("%s\n", name
);
1635 n
= ellipsize(name
, max_len
-len
, 100);
1643 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1645 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1646 [DEPENDENCY_FORWARD
] = "Requires\0"
1651 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1656 [DEPENDENCY_AFTER
] = "After\0",
1657 [DEPENDENCY_BEFORE
] = "Before\0",
1660 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1661 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1662 _cleanup_strv_free_
char **ret
= NULL
;
1663 _cleanup_free_
char *path
= NULL
;
1669 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1671 path
= unit_dbus_path_from_name(name
);
1675 r
= sd_bus_call_method(
1677 "org.freedesktop.systemd1",
1679 "org.freedesktop.DBus.Properties",
1683 "s", "org.freedesktop.systemd1.Unit");
1685 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1687 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1689 return bus_log_parse_error(r
);
1691 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1694 r
= sd_bus_message_read(reply
, "s", &prop
);
1696 return bus_log_parse_error(r
);
1698 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1699 r
= sd_bus_message_skip(reply
, "v");
1701 return bus_log_parse_error(r
);
1704 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1706 return bus_log_parse_error(r
);
1708 r
= bus_message_read_strv_extend(reply
, &ret
);
1710 return bus_log_parse_error(r
);
1712 r
= sd_bus_message_exit_container(reply
);
1714 return bus_log_parse_error(r
);
1717 r
= sd_bus_message_exit_container(reply
);
1719 return bus_log_parse_error(r
);
1723 return bus_log_parse_error(r
);
1725 r
= sd_bus_message_exit_container(reply
);
1727 return bus_log_parse_error(r
);
1729 *deps
= strv_uniq(ret
);
1735 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1736 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1738 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1740 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1743 return strcasecmp(*a
, *b
);
1746 static int list_dependencies_one(
1751 unsigned int branches
) {
1753 _cleanup_strv_free_
char **deps
= NULL
;
1761 r
= strv_extend(units
, name
);
1765 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1769 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1771 STRV_FOREACH(c
, deps
) {
1772 if (strv_contains(*units
, *c
)) {
1775 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1785 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1788 (void) get_state_one_unit(bus
, *c
, &active_state
);
1790 switch (active_state
) {
1792 case UNIT_RELOADING
:
1793 case UNIT_ACTIVATING
:
1794 on
= ansi_highlight_green();
1798 case UNIT_DEACTIVATING
:
1803 on
= ansi_highlight_red();
1807 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1810 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1814 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1815 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1822 strv_remove(*units
, name
);
1827 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1828 _cleanup_strv_free_
char **units
= NULL
;
1829 _cleanup_free_
char *unit
= NULL
;
1835 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1837 return log_error_errno(r
, "Failed to mangle unit name: %m");
1841 u
= SPECIAL_DEFAULT_TARGET
;
1843 r
= acquire_bus(BUS_MANAGER
, &bus
);
1847 pager_open(arg_no_pager
, false);
1851 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1854 struct machine_info
{
1858 char *control_group
;
1859 uint32_t n_failed_units
;
1864 static const struct bus_properties_map machine_info_property_map
[] = {
1865 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1866 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1867 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1868 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1869 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1873 static void machine_info_clear(struct machine_info
*info
) {
1878 free(info
->control_group
);
1882 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1888 for (i
= 0; i
< n
; i
++)
1889 machine_info_clear(&machine_infos
[i
]);
1891 free(machine_infos
);
1894 static int compare_machine_info(const void *a
, const void *b
) {
1895 const struct machine_info
*u
= a
, *v
= b
;
1897 if (u
->is_host
!= v
->is_host
)
1898 return u
->is_host
> v
->is_host
? -1 : 1;
1900 return strcasecmp(u
->name
, v
->name
);
1903 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1904 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1910 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1917 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, NULL
, mi
);
1924 static bool output_show_machine(const char *name
, char **patterns
) {
1925 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1928 static int get_machine_list(
1930 struct machine_info
**_machine_infos
,
1933 struct machine_info
*machine_infos
= NULL
;
1934 _cleanup_strv_free_
char **m
= NULL
;
1935 _cleanup_free_
char *hn
= NULL
;
1940 hn
= gethostname_malloc();
1944 if (output_show_machine(hn
, patterns
)) {
1945 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1948 machine_infos
[c
].is_host
= true;
1949 machine_infos
[c
].name
= hn
;
1952 (void) get_machine_properties(bus
, &machine_infos
[c
]);
1956 r
= sd_get_machine_names(&m
);
1958 return log_error_errno(r
, "Failed to get machine list: %m");
1960 STRV_FOREACH(i
, m
) {
1961 _cleanup_free_
char *class = NULL
;
1963 if (!output_show_machine(*i
, patterns
))
1966 sd_machine_get_class(*i
, &class);
1967 if (!streq_ptr(class, "container"))
1970 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1971 free_machines_list(machine_infos
, c
);
1975 machine_infos
[c
].is_host
= false;
1976 machine_infos
[c
].name
= strdup(*i
);
1977 if (!machine_infos
[c
].name
) {
1978 free_machines_list(machine_infos
, c
);
1982 (void) get_machine_properties(NULL
, &machine_infos
[c
]);
1986 *_machine_infos
= machine_infos
;
1990 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1991 struct machine_info
*m
;
1994 namelen
= sizeof("NAME") - 1,
1995 statelen
= sizeof("STATE") - 1,
1996 failedlen
= sizeof("FAILED") - 1,
1997 jobslen
= sizeof("JOBS") - 1;
1999 assert(machine_infos
|| n
== 0);
2001 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2002 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
2003 statelen
= MAX(statelen
, strlen_ptr(m
->state
));
2004 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
2005 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
2007 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
2011 if (!arg_no_legend
) {
2015 printf("%-*s %-*s %-*s %-*s\n",
2018 failedlen
, "FAILED",
2022 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2023 const char *on_state
= "", *off_state
= "";
2024 const char *on_failed
= "", *off_failed
= "";
2025 bool circle
= false;
2027 if (streq_ptr(m
->state
, "degraded")) {
2028 on_state
= ansi_highlight_red();
2029 off_state
= ansi_normal();
2031 } else if (!streq_ptr(m
->state
, "running")) {
2032 on_state
= ansi_highlight_yellow();
2033 off_state
= ansi_normal();
2037 if (m
->n_failed_units
> 0) {
2038 on_failed
= ansi_highlight_red();
2039 off_failed
= ansi_normal();
2041 on_failed
= off_failed
= "";
2044 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
2047 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2048 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
2049 on_state
, statelen
, strna(m
->state
), off_state
,
2050 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2051 jobslen
, m
->n_jobs
);
2053 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2054 namelen
, strna(m
->name
),
2055 on_state
, statelen
, strna(m
->state
), off_state
,
2056 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2057 jobslen
, m
->n_jobs
);
2061 printf("\n%u machines listed.\n", n
);
2064 static int list_machines(int argc
, char *argv
[], void *userdata
) {
2065 struct machine_info
*machine_infos
= NULL
;
2069 if (geteuid() != 0) {
2070 log_error("Must be root.");
2074 r
= acquire_bus(BUS_MANAGER
, &bus
);
2078 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2082 pager_open(arg_no_pager
, false);
2084 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2085 output_machines_list(machine_infos
, r
);
2086 free_machines_list(machine_infos
, r
);
2091 static int get_default(int argc
, char *argv
[], void *userdata
) {
2092 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2093 _cleanup_free_
char *_path
= NULL
;
2097 if (install_client_side()) {
2098 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2100 return log_error_errno(r
, "Failed to get default target: %m");
2105 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2108 r
= acquire_bus(BUS_MANAGER
, &bus
);
2112 r
= sd_bus_call_method(
2114 "org.freedesktop.systemd1",
2115 "/org/freedesktop/systemd1",
2116 "org.freedesktop.systemd1.Manager",
2122 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2124 r
= sd_bus_message_read(reply
, "s", &path
);
2126 return bus_log_parse_error(r
);
2130 printf("%s\n", path
);
2135 static int set_default(int argc
, char *argv
[], void *userdata
) {
2136 _cleanup_free_
char *unit
= NULL
;
2137 UnitFileChange
*changes
= NULL
;
2138 unsigned n_changes
= 0;
2144 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2146 return log_error_errno(r
, "Failed to mangle unit name: %m");
2148 if (install_client_side()) {
2149 r
= unit_file_set_default(arg_scope
, UNIT_FILE_FORCE
, arg_root
, unit
, &changes
, &n_changes
);
2150 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2155 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2156 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2159 polkit_agent_open_maybe();
2161 r
= acquire_bus(BUS_MANAGER
, &bus
);
2165 r
= sd_bus_call_method(
2167 "org.freedesktop.systemd1",
2168 "/org/freedesktop/systemd1",
2169 "org.freedesktop.systemd1.Manager",
2175 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2177 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2181 /* Try to reload if enabled */
2183 r
= daemon_reload(argc
, argv
, userdata
);
2189 unit_file_changes_free(changes
, n_changes
);
2194 static int output_waiting_jobs(sd_bus
*bus
, uint32_t id
, const char *method
, const char *prefix
) {
2195 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2196 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2197 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2203 r
= sd_bus_call_method(
2205 "org.freedesktop.systemd1",
2206 "/org/freedesktop/systemd1",
2207 "org.freedesktop.systemd1.Manager",
2213 return log_debug_errno(r
, "Failed to get waiting jobs for job %" PRIu32
, id
);
2215 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2217 return bus_log_parse_error(r
);
2219 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &other_id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0)
2220 printf("%s %u (%s/%s)\n", prefix
, other_id
, name
, type
);
2222 return bus_log_parse_error(r
);
2224 r
= sd_bus_message_exit_container(reply
);
2226 return bus_log_parse_error(r
);
2233 const char *name
, *type
, *state
;
2236 static void output_jobs_list(sd_bus
*bus
, const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2237 unsigned id_len
, unit_len
, type_len
, state_len
;
2238 const struct job_info
*j
;
2239 const char *on
, *off
;
2240 bool shorten
= false;
2242 assert(n
== 0 || jobs
);
2245 if (!arg_no_legend
) {
2246 on
= ansi_highlight_green();
2247 off
= ansi_normal();
2249 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2254 pager_open(arg_no_pager
, false);
2256 id_len
= strlen("JOB");
2257 unit_len
= strlen("UNIT");
2258 type_len
= strlen("TYPE");
2259 state_len
= strlen("STATE");
2261 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2262 uint32_t id
= j
->id
;
2263 assert(j
->name
&& j
->type
&& j
->state
);
2265 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2266 unit_len
= MAX(unit_len
, strlen(j
->name
));
2267 type_len
= MAX(type_len
, strlen(j
->type
));
2268 state_len
= MAX(state_len
, strlen(j
->state
));
2271 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2272 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2277 printf("%*s %-*s %-*s %-*s\n",
2281 state_len
, "STATE");
2283 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2284 _cleanup_free_
char *e
= NULL
;
2286 if (streq(j
->state
, "running")) {
2287 on
= ansi_highlight();
2288 off
= ansi_normal();
2292 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2293 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2295 on
, unit_len
, e
? e
: j
->name
, off
,
2297 on
, state_len
, j
->state
, off
);
2300 output_waiting_jobs(bus
, j
->id
, "GetJobAfter", "\twaiting for job");
2301 if (arg_jobs_before
)
2302 output_waiting_jobs(bus
, j
->id
, "GetJobBefore", "\tblocking job");
2305 if (!arg_no_legend
) {
2306 on
= ansi_highlight();
2307 off
= ansi_normal();
2309 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2313 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2314 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2317 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2318 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2319 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2320 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2321 _cleanup_free_
struct job_info
*jobs
= NULL
;
2327 bool skipped
= false;
2329 r
= acquire_bus(BUS_MANAGER
, &bus
);
2333 r
= sd_bus_call_method(
2335 "org.freedesktop.systemd1",
2336 "/org/freedesktop/systemd1",
2337 "org.freedesktop.systemd1.Manager",
2343 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2345 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2347 return bus_log_parse_error(r
);
2349 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2350 struct job_info job
= { id
, name
, type
, state
};
2352 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2357 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2363 return bus_log_parse_error(r
);
2365 r
= sd_bus_message_exit_container(reply
);
2367 return bus_log_parse_error(r
);
2369 pager_open(arg_no_pager
, false);
2371 output_jobs_list(bus
, jobs
, c
, skipped
);
2375 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2381 return trivial_method(argc
, argv
, userdata
);
2383 r
= acquire_bus(BUS_MANAGER
, &bus
);
2387 polkit_agent_open_maybe();
2389 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2390 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2394 q
= safe_atou32(*name
, &id
);
2396 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2398 q
= sd_bus_call_method(
2400 "org.freedesktop.systemd1",
2401 "/org/freedesktop/systemd1",
2402 "org.freedesktop.systemd1.Manager",
2408 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2417 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2418 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2422 /* We ignore all errors here, since this is used to show a
2425 /* We don't use unit_dbus_path_from_name() directly since we
2426 * don't want to load the unit if it isn't loaded. */
2428 r
= sd_bus_call_method(
2430 "org.freedesktop.systemd1",
2431 "/org/freedesktop/systemd1",
2432 "org.freedesktop.systemd1.Manager",
2440 r
= sd_bus_message_read(reply
, "o", &path
);
2444 r
= sd_bus_get_property_trivial(
2446 "org.freedesktop.systemd1",
2448 "org.freedesktop.systemd1.Unit",
2458 static void warn_unit_file_changed(const char *name
) {
2461 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2462 ansi_highlight_red(),
2465 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2468 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2474 STRV_FOREACH(p
, lp
->search_path
) {
2475 _cleanup_free_
char *path
= NULL
, *lpath
= NULL
;
2478 path
= path_join(NULL
, *p
, unit_name
);
2482 r
= chase_symlinks(path
, arg_root
, 0, &lpath
);
2488 return log_error_errno(r
, "Failed to access path '%s': %m", path
);
2500 static int unit_find_template_path(
2501 const char *unit_name
,
2503 char **fragment_path
,
2506 _cleanup_free_
char *_template
= NULL
;
2509 /* Returns 1 if a fragment was found, 0 if not found, negative on error. */
2511 r
= unit_file_find_path(lp
, unit_name
, fragment_path
);
2513 return r
; /* error or found a real unit */
2515 r
= unit_name_template(unit_name
, &_template
);
2517 return 0; /* not a template, does not exist */
2519 return log_error_errno(r
, "Failed to determine template name: %m");
2521 r
= unit_file_find_path(lp
, _template
, fragment_path
);
2526 *template = _template
;
2532 static int unit_find_paths(
2534 const char *unit_name
,
2536 char **fragment_path
,
2537 char ***dropin_paths
) {
2539 _cleanup_free_
char *path
= NULL
;
2540 _cleanup_strv_free_
char **dropins
= NULL
;
2544 * Finds where the unit is defined on disk. Returns 0 if the unit
2545 * is not found. Returns 1 if it is found, and sets
2546 * - the path to the unit in *path, if it exists on disk,
2547 * - and a strv of existing drop-ins in *dropins,
2548 * if the arg is not NULL and any dropins were found.
2552 assert(fragment_path
);
2555 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2556 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2557 _cleanup_free_
char *unit
= NULL
;
2559 unit
= unit_dbus_path_from_name(unit_name
);
2563 r
= sd_bus_get_property_string(
2565 "org.freedesktop.systemd1",
2567 "org.freedesktop.systemd1.Unit",
2572 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2575 r
= sd_bus_get_property_strv(
2577 "org.freedesktop.systemd1",
2579 "org.freedesktop.systemd1.Unit",
2584 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2587 _cleanup_set_free_ Set
*names
= NULL
;
2588 _cleanup_free_
char *template = NULL
;
2590 names
= set_new(NULL
);
2594 r
= unit_find_template_path(unit_name
, lp
, &path
, &template);
2599 /* We found the unit file. If we followed symlinks, this name might be
2600 * different then the unit_name with started with. Look for dropins matching
2601 * that "final" name. */
2602 r
= set_put(names
, basename(path
));
2604 /* No unit file, let's look for dropins matching the original name.
2605 * systemd has fairly complicated rules (based on unit type and provenience),
2606 * which units are allowed not to have the main unit file. We err on the
2607 * side of including too many files, and always try to load dropins. */
2608 r
= set_put(names
, unit_name
);
2610 /* The cases where we allow a unit to exist without the main file are
2611 * never valid for templates. Don't try to load dropins in this case. */
2615 return log_error_errno(r
, "Failed to add unit name: %m");
2618 r
= unit_file_find_dropin_conf_paths(arg_root
, lp
->search_path
,
2619 NULL
, names
, &dropins
);
2627 if (!isempty(path
)) {
2628 *fragment_path
= path
;
2633 if (dropin_paths
&& !strv_isempty(dropins
)) {
2634 *dropin_paths
= dropins
;
2639 if (r
== 0 && !arg_force
)
2640 log_error("No files found for %s.", unit_name
);
2645 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2646 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2647 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2648 _cleanup_free_
char *buf
= NULL
;
2649 UnitActiveState state
;
2654 assert(active_state
);
2656 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2658 r
= sd_bus_call_method(
2660 "org.freedesktop.systemd1",
2661 "/org/freedesktop/systemd1",
2662 "org.freedesktop.systemd1.Manager",
2668 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2669 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2671 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2672 * considered inactive. */
2673 state
= UNIT_INACTIVE
;
2676 r
= sd_bus_message_read(reply
, "o", &path
);
2678 return bus_log_parse_error(r
);
2680 r
= sd_bus_get_property_string(
2682 "org.freedesktop.systemd1",
2684 "org.freedesktop.systemd1.Unit",
2689 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2691 state
= unit_active_state_from_string(buf
);
2692 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2693 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2698 *active_state
= state
;
2702 static int check_triggering_units(
2706 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2707 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2708 _cleanup_strv_free_
char **triggered_by
= NULL
;
2709 bool print_warning_label
= true;
2710 UnitActiveState active_state
;
2714 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2716 return log_error_errno(r
, "Failed to mangle unit name: %m");
2718 path
= unit_dbus_path_from_name(n
);
2722 r
= sd_bus_get_property_string(
2724 "org.freedesktop.systemd1",
2726 "org.freedesktop.systemd1.Unit",
2731 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2733 if (streq(load_state
, "masked"))
2736 r
= sd_bus_get_property_strv(
2738 "org.freedesktop.systemd1",
2740 "org.freedesktop.systemd1.Unit",
2745 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2747 STRV_FOREACH(i
, triggered_by
) {
2748 r
= get_state_one_unit(bus
, *i
, &active_state
);
2752 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2755 if (print_warning_label
) {
2756 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2757 print_warning_label
= false;
2760 log_warning(" %s", *i
);
2766 static const struct {
2769 } unit_actions
[] = {
2770 { "start", "StartUnit" },
2771 { "stop", "StopUnit" },
2772 { "condstop", "StopUnit" },
2773 { "reload", "ReloadUnit" },
2774 { "restart", "RestartUnit" },
2775 { "try-restart", "TryRestartUnit" },
2776 { "condrestart", "TryRestartUnit" },
2777 { "reload-or-restart", "ReloadOrRestartUnit" },
2778 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2779 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2780 { "condreload", "ReloadOrTryRestartUnit" },
2781 { "force-reload", "ReloadOrTryRestartUnit" }
2784 static const char *verb_to_method(const char *verb
) {
2787 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2788 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2789 return unit_actions
[i
].method
;
2794 static const char *method_to_verb(const char *method
) {
2797 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2798 if (streq_ptr(unit_actions
[i
].method
, method
))
2799 return unit_actions
[i
].verb
;
2811 static void wait_context_free(WaitContext
*c
) {
2812 c
->match
= sd_bus_slot_unref(c
->match
);
2813 c
->event
= sd_event_unref(c
->event
);
2814 c
->unit_paths
= set_free_free(c
->unit_paths
);
2817 static int on_properties_changed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
2818 WaitContext
*c
= userdata
;
2822 path
= sd_bus_message_get_path(m
);
2823 if (!set_contains(c
->unit_paths
, path
))
2826 /* Check if ActiveState changed to inactive/failed */
2827 /* (s interface, a{sv} changed_properties, as invalidated_properties) */
2828 r
= sd_bus_message_skip(m
, "s");
2830 return bus_log_parse_error(r
);
2832 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
2834 return bus_log_parse_error(r
);
2836 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
2839 r
= sd_bus_message_read(m
, "s", &s
);
2841 return bus_log_parse_error(r
);
2843 if (streq(s
, "ActiveState")) {
2846 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, "s");
2848 return bus_log_parse_error(r
);
2850 r
= sd_bus_message_read(m
, "s", &s
);
2852 return bus_log_parse_error(r
);
2854 is_failed
= streq(s
, "failed");
2855 if (streq(s
, "inactive") || is_failed
) {
2856 log_debug("%s became %s, dropping from --wait tracking", path
, s
);
2857 free(set_remove(c
->unit_paths
, path
));
2858 c
->any_failed
= c
->any_failed
|| is_failed
;
2860 log_debug("ActiveState on %s changed to %s", path
, s
);
2862 break; /* no need to dissect the rest of the message */
2864 /* other property */
2865 r
= sd_bus_message_skip(m
, "v");
2867 return bus_log_parse_error(r
);
2869 r
= sd_bus_message_exit_container(m
);
2871 return bus_log_parse_error(r
);
2874 return bus_log_parse_error(r
);
2876 if (set_isempty(c
->unit_paths
))
2877 sd_event_exit(c
->event
, EXIT_SUCCESS
);
2882 static int start_unit_one(
2887 sd_bus_error
*error
,
2889 WaitContext
*wait_context
) {
2891 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2901 _cleanup_free_
char *unit_path
= NULL
;
2904 log_debug("Watching for property changes of %s", name
);
2905 r
= sd_bus_call_method(
2907 "org.freedesktop.systemd1",
2908 "/org/freedesktop/systemd1",
2909 "org.freedesktop.systemd1.Manager",
2915 return log_error_errno(r
, "Failed to RefUnit %s: %s", name
, bus_error_message(error
, r
));
2917 unit_path
= unit_dbus_path_from_name(name
);
2921 r
= set_put_strdup(wait_context
->unit_paths
, unit_path
);
2923 return log_error_errno(r
, "Failed to add unit path %s to set: %m", unit_path
);
2925 mt
= strjoina("type='signal',"
2926 "interface='org.freedesktop.DBus.Properties',"
2927 "path='", unit_path
, "',"
2928 "member='PropertiesChanged'");
2929 r
= sd_bus_add_match(bus
, &wait_context
->match
, mt
, on_properties_changed
, wait_context
);
2931 return log_error_errno(r
, "Failed to add match for PropertiesChanged signal: %m");
2934 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2936 r
= sd_bus_call_method(
2938 "org.freedesktop.systemd1",
2939 "/org/freedesktop/systemd1",
2940 "org.freedesktop.systemd1.Manager",
2948 /* There's always a fallback possible for legacy actions. */
2949 if (arg_action
!= ACTION_SYSTEMCTL
)
2952 verb
= method_to_verb(method
);
2954 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2956 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2957 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2958 log_error("See %s logs and 'systemctl%s status%s %s' for details.",
2959 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2960 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2961 name
[0] == '-' ? " --" : "",
2967 r
= sd_bus_message_read(reply
, "o", &path
);
2969 return bus_log_parse_error(r
);
2971 if (need_daemon_reload(bus
, name
) > 0)
2972 warn_unit_file_changed(name
);
2975 log_debug("Adding %s to the set", path
);
2976 r
= bus_wait_for_jobs_add(w
, path
);
2984 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2985 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2992 STRV_FOREACH(name
, names
) {
2996 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2998 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
3000 return log_error_errno(r
, "Failed to mangle name: %m");
3002 if (string_is_glob(t
))
3003 r
= strv_consume(&globs
, t
);
3005 r
= strv_consume(&mangled
, t
);
3010 /* Query the manager only if any of the names are a glob, since
3011 * this is fairly expensive */
3012 if (!strv_isempty(globs
)) {
3013 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3014 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
3015 size_t allocated
, n
;
3017 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
3021 n
= strv_length(mangled
);
3024 for (i
= 0; i
< r
; i
++) {
3025 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
3028 mangled
[n
] = strdup(unit_infos
[i
].id
);
3032 mangled
[++n
] = NULL
;
3037 mangled
= NULL
; /* do not free */
3042 static const struct {
3046 } action_table
[_ACTION_MAX
] = {
3047 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
3048 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
3049 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
3050 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
3051 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3052 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3053 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3054 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
3055 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
3056 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
3057 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
3058 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
3059 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
3060 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
3061 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
3064 static enum action
verb_to_action(const char *verb
) {
3067 for (i
= 0; i
< _ACTION_MAX
; i
++)
3068 if (streq_ptr(action_table
[i
].verb
, verb
))
3071 return _ACTION_INVALID
;
3074 static int start_unit(int argc
, char *argv
[], void *userdata
) {
3075 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
3076 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
3077 _cleanup_strv_free_
char **names
= NULL
;
3079 _cleanup_(wait_context_free
) WaitContext wait_context
= {};
3083 if (arg_wait
&& !STR_IN_SET(argv
[0], "start", "restart")) {
3084 log_error("--wait may only be used with the 'start' or 'restart' commands.");
3088 /* we cannot do sender tracking on the private bus, so we need the full
3089 * one for RefUnit to implement --wait */
3090 r
= acquire_bus(arg_wait
? BUS_FULL
: BUS_MANAGER
, &bus
);
3094 ask_password_agent_open_if_enabled();
3095 polkit_agent_open_maybe();
3097 if (arg_action
== ACTION_SYSTEMCTL
) {
3100 action
= verb_to_action(argv
[0]);
3102 if (action
!= _ACTION_INVALID
) {
3103 method
= "StartUnit";
3104 mode
= action_table
[action
].mode
;
3105 one_name
= action_table
[action
].target
;
3107 if (streq(argv
[0], "isolate")) {
3108 method
= "StartUnit";
3113 method
= verb_to_method(argv
[0]);
3114 mode
= arg_job_mode
;
3119 assert(arg_action
>= 0 && arg_action
< _ACTION_MAX
);
3120 assert(action_table
[arg_action
].target
);
3121 assert(action_table
[arg_action
].mode
);
3123 method
= "StartUnit";
3124 mode
= action_table
[arg_action
].mode
;
3125 one_name
= action_table
[arg_action
].target
;
3129 names
= strv_new(one_name
, NULL
);
3131 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
3133 return log_error_errno(r
, "Failed to expand names: %m");
3136 if (!arg_no_block
) {
3137 r
= bus_wait_for_jobs_new(bus
, &w
);
3139 return log_error_errno(r
, "Could not watch jobs: %m");
3143 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3145 wait_context
.unit_paths
= set_new(&string_hash_ops
);
3146 if (!wait_context
.unit_paths
)
3149 r
= sd_bus_call_method(
3151 "org.freedesktop.systemd1",
3152 "/org/freedesktop/systemd1",
3153 "org.freedesktop.systemd1.Manager",
3158 return log_error_errno(r
, "Failed to enable subscription: %s", bus_error_message(&error
, r
));
3159 r
= sd_event_default(&wait_context
.event
);
3161 return log_error_errno(r
, "Failed to allocate event loop: %m");
3162 r
= sd_bus_attach_event(bus
, wait_context
.event
, 0);
3164 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
3167 STRV_FOREACH(name
, names
) {
3168 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3171 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
, arg_wait
? &wait_context
: NULL
);
3172 if (r
>= 0 && q
< 0)
3173 r
= translate_bus_error_to_exit_status(q
, &error
);
3176 if (!arg_no_block
) {
3177 int q
, arg_count
= 0;
3178 const char* extra_args
[4] = {};
3180 if (arg_scope
!= UNIT_FILE_SYSTEM
)
3181 extra_args
[arg_count
++] = "--user";
3183 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
3184 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
3185 extra_args
[arg_count
++] = "-H";
3186 extra_args
[arg_count
++] = arg_host
;
3187 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
3188 extra_args
[arg_count
++] = "-M";
3189 extra_args
[arg_count
++] = arg_host
;
3192 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
3196 /* When stopping units, warn if they can still be triggered by
3197 * another active unit (socket, path, timer) */
3198 if (!arg_quiet
&& streq(method
, "StopUnit"))
3199 STRV_FOREACH(name
, names
)
3200 check_triggering_units(bus
, *name
);
3203 if (r
>= 0 && arg_wait
) {
3205 q
= sd_event_loop(wait_context
.event
);
3207 return log_error_errno(q
, "Failed to run event loop: %m");
3208 if (wait_context
.any_failed
)
3216 static int logind_set_wall_message(void) {
3217 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3219 _cleanup_free_
char *m
= NULL
;
3222 r
= acquire_bus(BUS_FULL
, &bus
);
3226 m
= strv_join(arg_wall
, " ");
3230 r
= sd_bus_call_method(
3232 "org.freedesktop.login1",
3233 "/org/freedesktop/login1",
3234 "org.freedesktop.login1.Manager",
3243 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
3248 /* Ask systemd-logind, which might grant access to unprivileged users
3249 * through PolicyKit */
3250 static int logind_reboot(enum action a
) {
3252 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3253 const char *method
, *description
;
3257 r
= acquire_bus(BUS_FULL
, &bus
);
3263 case ACTION_POWEROFF
:
3264 method
= "PowerOff";
3265 description
= "power off system";
3270 description
= "reboot system";
3275 description
= "halt system";
3278 case ACTION_SUSPEND
:
3280 description
= "suspend system";
3283 case ACTION_HIBERNATE
:
3284 method
= "Hibernate";
3285 description
= "hibernate system";
3288 case ACTION_HYBRID_SLEEP
:
3289 method
= "HybridSleep";
3290 description
= "put system into hybrid sleep";
3297 polkit_agent_open_maybe();
3298 (void) logind_set_wall_message();
3300 r
= sd_bus_call_method(
3302 "org.freedesktop.login1",
3303 "/org/freedesktop/login1",
3304 "org.freedesktop.login1.Manager",
3308 "b", arg_ask_password
);
3310 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
3318 static int logind_check_inhibitors(enum action a
) {
3320 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3321 _cleanup_strv_free_
char **sessions
= NULL
;
3322 const char *what
, *who
, *why
, *mode
;
3329 if (arg_ignore_inhibitors
|| arg_force
> 0)
3341 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
3344 r
= acquire_bus(BUS_FULL
, &bus
);
3348 r
= sd_bus_call_method(
3350 "org.freedesktop.login1",
3351 "/org/freedesktop/login1",
3352 "org.freedesktop.login1.Manager",
3358 /* If logind is not around, then there are no inhibitors... */
3361 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3363 return bus_log_parse_error(r
);
3365 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3366 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3367 _cleanup_strv_free_
char **sv
= NULL
;
3369 if (!streq(mode
, "block"))
3372 sv
= strv_split(what
, ":");
3376 if (!pid_is_valid((pid_t
) pid
)) {
3377 log_error("Invalid PID "PID_FMT
".", (pid_t
) pid
);
3381 if (!strv_contains(sv
,
3386 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3389 get_process_comm(pid
, &comm
);
3390 user
= uid_to_name(uid
);
3392 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3393 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3398 return bus_log_parse_error(r
);
3400 r
= sd_bus_message_exit_container(reply
);
3402 return bus_log_parse_error(r
);
3404 /* Check for current sessions */
3405 sd_get_sessions(&sessions
);
3406 STRV_FOREACH(s
, sessions
) {
3407 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3409 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3412 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3415 if (sd_session_get_type(*s
, &type
) < 0 || !STR_IN_SET(type
, "x11", "tty"))
3418 sd_session_get_tty(*s
, &tty
);
3419 sd_session_get_seat(*s
, &seat
);
3420 sd_session_get_service(*s
, &service
);
3421 user
= uid_to_name(uid
);
3423 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3430 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3431 action_table
[a
].verb
);
3439 static int logind_prepare_firmware_setup(void) {
3441 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3445 r
= acquire_bus(BUS_FULL
, &bus
);
3449 r
= sd_bus_call_method(
3451 "org.freedesktop.login1",
3452 "/org/freedesktop/login1",
3453 "org.freedesktop.login1.Manager",
3454 "SetRebootToFirmwareSetup",
3459 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3463 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3468 static int prepare_firmware_setup(void) {
3471 if (!arg_firmware_setup
)
3474 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3476 r
= efi_set_reboot_to_firmware(true);
3478 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3483 return logind_prepare_firmware_setup();
3486 static int set_exit_code(uint8_t code
) {
3487 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3491 r
= acquire_bus(BUS_MANAGER
, &bus
);
3495 r
= sd_bus_call_method(
3497 "org.freedesktop.systemd1",
3498 "/org/freedesktop/systemd1",
3499 "org.freedesktop.systemd1.Manager",
3505 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3510 static int start_special(int argc
, char *argv
[], void *userdata
) {
3513 bool termination_action
; /* an action that terminates the manager,
3514 * can be performed also by signal. */
3518 a
= verb_to_action(argv
[0]);
3520 r
= logind_check_inhibitors(a
);
3524 if (arg_force
>= 2 && geteuid() != 0) {
3525 log_error("Must be root.");
3529 r
= prepare_firmware_setup();
3533 if (a
== ACTION_REBOOT
&& argc
> 1) {
3534 r
= update_reboot_parameter_and_warn(argv
[1]);
3538 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3541 /* If the exit code is not given on the command line,
3542 * don't reset it to zero: just keep it as it might
3543 * have been set previously. */
3545 r
= safe_atou8(argv
[1], &code
);
3547 return log_error_errno(r
, "Invalid exit code.");
3549 r
= set_exit_code(code
);
3554 termination_action
= IN_SET(a
,
3558 if (termination_action
&& arg_force
>= 2)
3561 if (arg_force
>= 1 &&
3562 (termination_action
|| IN_SET(a
, ACTION_KEXEC
, ACTION_EXIT
)))
3563 r
= trivial_method(argc
, argv
, userdata
);
3565 /* First try logind, to allow authentication with polkit */
3572 ACTION_HYBRID_SLEEP
)) {
3574 r
= logind_reboot(a
);
3577 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3578 /* requested operation is not supported or already in progress */
3581 /* On all other errors, try low-level operation. In order to minimize the difference between
3582 * operation with and without logind, we explicitly enable non-blocking mode for this, as
3583 * logind's shutdown operations are always non-blocking. */
3585 arg_no_block
= true;
3587 } else if (IN_SET(a
, ACTION_EXIT
, ACTION_KEXEC
))
3588 /* Since exit/kexec are so close in behaviour to power-off/reboot, let's also make them
3589 * asynchronous, in order to not confuse the user needlessly with unexpected behaviour. */
3590 arg_no_block
= true;
3592 r
= start_unit(argc
, argv
, userdata
);
3595 if (termination_action
&& arg_force
< 2 &&
3596 IN_SET(r
, -ENOENT
, -ETIMEDOUT
))
3597 log_notice("It is possible to perform action directly, see discussion of --force --force in man:systemctl(1).");
3602 static int start_system_special(int argc
, char *argv
[], void *userdata
) {
3603 /* Like start_special above, but raises an error when running in user mode */
3605 if (arg_scope
!= UNIT_FILE_SYSTEM
) {
3606 log_error("Bad action for %s mode.",
3607 arg_scope
== UNIT_FILE_GLOBAL
? "--global" : "--user");
3611 return start_special(argc
, argv
, userdata
);
3614 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3615 _cleanup_strv_free_
char **names
= NULL
;
3616 UnitActiveState active_state
;
3622 r
= acquire_bus(BUS_MANAGER
, &bus
);
3626 r
= expand_names(bus
, args
, NULL
, &names
);
3628 return log_error_errno(r
, "Failed to expand names: %m");
3630 STRV_FOREACH(name
, names
) {
3631 r
= get_state_one_unit(bus
, *name
, &active_state
);
3636 puts(unit_active_state_to_string(active_state
));
3638 for (i
= 0; i
< nb_states
; ++i
)
3639 if (good_states
[i
] == active_state
)
3643 /* use the given return code for the case that we won't find
3644 * any unit which matches the list */
3645 return found
? 0 : code
;
3648 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3649 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3650 /* According to LSB: 3, "program is not running" */
3651 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3654 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3655 const UnitActiveState states
[] = { UNIT_FAILED
};
3656 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3659 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3660 _cleanup_strv_free_
char **names
= NULL
;
3661 char *kill_who
= NULL
, **name
;
3665 r
= acquire_bus(BUS_MANAGER
, &bus
);
3669 polkit_agent_open_maybe();
3672 arg_kill_who
= "all";
3674 /* --fail was specified */
3675 if (streq(arg_job_mode
, "fail"))
3676 kill_who
= strjoina(arg_kill_who
, "-fail");
3678 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3680 return log_error_errno(r
, "Failed to expand names: %m");
3682 STRV_FOREACH(name
, names
) {
3683 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3685 q
= sd_bus_call_method(
3687 "org.freedesktop.systemd1",
3688 "/org/freedesktop/systemd1",
3689 "org.freedesktop.systemd1.Manager",
3693 "ssi", *name
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3695 log_error_errno(q
, "Failed to kill unit %s: %s", *name
, bus_error_message(&error
, q
));
3704 typedef struct ExecStatusInfo
{
3712 usec_t start_timestamp
;
3713 usec_t exit_timestamp
;
3718 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3721 static void exec_status_info_free(ExecStatusInfo
*i
) {
3730 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3731 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3734 int32_t code
, status
;
3740 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3742 return bus_log_parse_error(r
);
3746 r
= sd_bus_message_read(m
, "s", &path
);
3748 return bus_log_parse_error(r
);
3750 i
->path
= strdup(path
);
3754 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3756 return bus_log_parse_error(r
);
3758 r
= sd_bus_message_read(m
,
3761 &start_timestamp
, &start_timestamp_monotonic
,
3762 &exit_timestamp
, &exit_timestamp_monotonic
,
3766 return bus_log_parse_error(r
);
3769 i
->start_timestamp
= (usec_t
) start_timestamp
;
3770 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3771 i
->pid
= (pid_t
) pid
;
3775 r
= sd_bus_message_exit_container(m
);
3777 return bus_log_parse_error(r
);
3782 typedef struct UnitCondition
{
3789 LIST_FIELDS(struct UnitCondition
, conditions
);
3792 static void unit_condition_free(UnitCondition
*c
) {
3801 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition
*, unit_condition_free
);
3803 typedef struct UnitStatusInfo
{
3805 const char *load_state
;
3806 const char *active_state
;
3807 const char *sub_state
;
3808 const char *unit_file_state
;
3809 const char *unit_file_preset
;
3811 const char *description
;
3812 const char *following
;
3814 char **documentation
;
3816 const char *fragment_path
;
3817 const char *source_path
;
3818 const char *control_group
;
3820 char **dropin_paths
;
3822 const char *load_error
;
3825 usec_t inactive_exit_timestamp
;
3826 usec_t inactive_exit_timestamp_monotonic
;
3827 usec_t active_enter_timestamp
;
3828 usec_t active_exit_timestamp
;
3829 usec_t inactive_enter_timestamp
;
3831 bool need_daemon_reload
;
3837 const char *status_text
;
3838 const char *pid_file
;
3842 usec_t start_timestamp
;
3843 usec_t exit_timestamp
;
3845 int exit_code
, exit_status
;
3847 usec_t condition_timestamp
;
3848 bool condition_result
;
3849 LIST_HEAD(UnitCondition
, conditions
);
3851 usec_t assert_timestamp
;
3853 bool failed_assert_trigger
;
3854 bool failed_assert_negate
;
3855 const char *failed_assert
;
3856 const char *failed_assert_parameter
;
3857 usec_t next_elapse_real
;
3858 usec_t next_elapse_monotonic
;
3861 unsigned n_accepted
;
3862 unsigned n_connections
;
3865 /* Pairs of type, path */
3869 const char *sysfs_path
;
3871 /* Mount, Automount */
3878 uint64_t memory_current
;
3879 uint64_t memory_low
;
3880 uint64_t memory_high
;
3881 uint64_t memory_max
;
3882 uint64_t memory_swap_max
;
3883 uint64_t memory_limit
;
3884 uint64_t cpu_usage_nsec
;
3885 uint64_t tasks_current
;
3888 uint64_t ip_ingress_bytes
;
3889 uint64_t ip_egress_bytes
;
3891 LIST_HEAD(ExecStatusInfo
, exec
);
3894 static void unit_status_info_free(UnitStatusInfo
*info
) {
3898 strv_free(info
->documentation
);
3899 strv_free(info
->dropin_paths
);
3900 strv_free(info
->listen
);
3902 while ((c
= info
->conditions
)) {
3903 LIST_REMOVE(conditions
, info
->conditions
, c
);
3904 unit_condition_free(c
);
3907 while ((p
= info
->exec
)) {
3908 LIST_REMOVE(exec
, info
->exec
, p
);
3909 exec_status_info_free(p
);
3913 static void print_status_info(
3919 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3921 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3922 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3929 /* This shows pretty information about a unit. See
3930 * print_property() for a low-level property printer */
3932 if (streq_ptr(i
->active_state
, "failed")) {
3933 active_on
= ansi_highlight_red();
3934 active_off
= ansi_normal();
3935 } else if (STRPTR_IN_SET(i
->active_state
, "active", "reloading")) {
3936 active_on
= ansi_highlight_green();
3937 active_off
= ansi_normal();
3939 active_on
= active_off
= "";
3941 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3943 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3944 printf(" - %s", i
->description
);
3949 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3951 if (streq_ptr(i
->load_state
, "error")) {
3952 on
= ansi_highlight_red();
3953 off
= ansi_normal();
3957 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3959 if (i
->load_error
!= 0)
3960 printf(" Loaded: %s%s%s (Reason: %s)\n",
3961 on
, strna(i
->load_state
), off
, i
->load_error
);
3962 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3963 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3964 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3965 else if (path
&& !isempty(i
->unit_file_state
))
3966 printf(" Loaded: %s%s%s (%s; %s)\n",
3967 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3969 printf(" Loaded: %s%s%s (%s)\n",
3970 on
, strna(i
->load_state
), off
, path
);
3972 printf(" Loaded: %s%s%s\n",
3973 on
, strna(i
->load_state
), off
);
3976 printf("Transient: yes\n");
3978 if (!strv_isempty(i
->dropin_paths
)) {
3979 _cleanup_free_
char *dir
= NULL
;
3983 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3984 if (! dir
|| last
) {
3985 printf(dir
? " " : " Drop-In: ");
3989 dir
= dirname_malloc(*dropin
);
3995 printf("%s\n %s", dir
,
3996 special_glyph(TREE_RIGHT
));
3999 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
4001 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
4005 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
4007 printf(" Active: %s%s (%s)%s",
4008 active_on
, strna(i
->active_state
), ss
, active_off
);
4010 printf(" Active: %s%s%s",
4011 active_on
, strna(i
->active_state
), active_off
);
4013 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
4014 printf(" (Result: %s)", i
->result
);
4016 timestamp
= STRPTR_IN_SET(i
->active_state
, "active", "reloading") ? i
->active_enter_timestamp
:
4017 STRPTR_IN_SET(i
->active_state
, "inactive", "failed") ? i
->inactive_enter_timestamp
:
4018 STRPTR_IN_SET(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
4019 i
->active_exit_timestamp
;
4021 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
4022 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
4025 printf(" since %s; %s\n", s2
, s1
);
4027 printf(" since %s\n", s2
);
4031 if (endswith(i
->id
, ".timer")) {
4032 char tstamp1
[FORMAT_TIMESTAMP_RELATIVE_MAX
],
4033 tstamp2
[FORMAT_TIMESTAMP_MAX
];
4034 char *next_rel_time
, *next_time
;
4035 dual_timestamp nw
, next
= {i
->next_elapse_real
,
4036 i
->next_elapse_monotonic
};
4039 printf(" Trigger: ");
4041 dual_timestamp_get(&nw
);
4042 next_elapse
= calc_next_elapse(&nw
, &next
);
4043 next_rel_time
= format_timestamp_relative(tstamp1
,
4046 next_time
= format_timestamp(tstamp2
,
4050 if (next_time
&& next_rel_time
)
4051 printf("%s; %s\n", next_time
, next_rel_time
);
4056 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
4060 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
4061 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
4063 printf("Condition: start %scondition failed%s at %s%s%s\n",
4064 ansi_highlight_yellow(), ansi_normal(),
4065 s2
, s1
? "; " : "", strempty(s1
));
4067 LIST_FOREACH(conditions
, c
, i
->conditions
)
4068 if (c
->tristate
< 0)
4071 LIST_FOREACH(conditions
, c
, i
->conditions
)
4072 if (c
->tristate
< 0)
4073 printf(" %s %s=%s%s%s was not met\n",
4074 --n
? special_glyph(TREE_BRANCH
) : special_glyph(TREE_RIGHT
),
4076 c
->trigger
? "|" : "",
4077 c
->negate
? "!" : "",
4081 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
4082 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
4083 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
4085 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
4086 ansi_highlight_red(), ansi_normal(),
4087 s2
, s1
? "; " : "", strempty(s1
));
4088 if (i
->failed_assert_trigger
)
4089 printf(" none of the trigger assertions were met\n");
4090 else if (i
->failed_assert
)
4091 printf(" %s=%s%s was not met\n",
4093 i
->failed_assert_negate
? "!" : "",
4094 i
->failed_assert_parameter
);
4098 printf(" Device: %s\n", i
->sysfs_path
);
4100 printf(" Where: %s\n", i
->where
);
4102 printf(" What: %s\n", i
->what
);
4104 STRV_FOREACH(t
, i
->documentation
)
4105 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
4107 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
4108 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
4111 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
4113 LIST_FOREACH(exec
, p
, i
->exec
) {
4114 _cleanup_free_
char *argv
= NULL
;
4117 /* Only show exited processes here */
4121 argv
= strv_join(p
->argv
, " ");
4122 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
4124 good
= is_clean_exit(p
->code
, p
->status
, EXIT_CLEAN_DAEMON
, NULL
);
4126 on
= ansi_highlight_red();
4127 off
= ansi_normal();
4131 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
4133 if (p
->code
== CLD_EXITED
) {
4136 printf("status=%i", p
->status
);
4138 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
4143 printf("signal=%s", signal_to_string(p
->status
));
4145 printf(")%s\n", off
);
4147 if (i
->main_pid
== p
->pid
&&
4148 i
->start_timestamp
== p
->start_timestamp
&&
4149 i
->exit_timestamp
== p
->start_timestamp
)
4150 /* Let's not show this twice */
4153 if (p
->pid
== i
->control_pid
)
4157 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
4158 if (i
->main_pid
> 0) {
4159 printf(" Main PID: "PID_FMT
, i
->main_pid
);
4162 _cleanup_free_
char *comm
= NULL
;
4163 (void) get_process_comm(i
->main_pid
, &comm
);
4165 printf(" (%s)", comm
);
4166 } else if (i
->exit_code
> 0) {
4167 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
4169 if (i
->exit_code
== CLD_EXITED
) {
4172 printf("status=%i", i
->exit_status
);
4174 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
4179 printf("signal=%s", signal_to_string(i
->exit_status
));
4184 if (i
->control_pid
> 0) {
4185 _cleanup_free_
char *c
= NULL
;
4187 if (i
->main_pid
> 0)
4188 fputs("; Control PID: ", stdout
);
4190 fputs("Cntrl PID: ", stdout
); /* if first in column, abbreviated so it fits alignment */
4192 printf(PID_FMT
, i
->control_pid
);
4194 (void) get_process_comm(i
->control_pid
, &c
);
4203 printf(" Status: \"%s\"\n", i
->status_text
);
4204 if (i
->status_errno
> 0)
4205 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
4207 if (i
->ip_ingress_bytes
!= (uint64_t) -1 && i
->ip_egress_bytes
!= (uint64_t) -1) {
4208 char buf_in
[FORMAT_BYTES_MAX
], buf_out
[FORMAT_BYTES_MAX
];
4210 printf(" IP: %s in, %s out\n",
4211 format_bytes(buf_in
, sizeof(buf_in
), i
->ip_ingress_bytes
),
4212 format_bytes(buf_out
, sizeof(buf_out
), i
->ip_egress_bytes
));
4215 if (i
->tasks_current
!= (uint64_t) -1) {
4216 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
4218 if (i
->tasks_max
!= (uint64_t) -1)
4219 printf(" (limit: %" PRIu64
")\n", i
->tasks_max
);
4224 if (i
->memory_current
!= (uint64_t) -1) {
4225 char buf
[FORMAT_BYTES_MAX
];
4227 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
4229 if (i
->memory_low
> 0 || i
->memory_high
!= CGROUP_LIMIT_MAX
||
4230 i
->memory_max
!= CGROUP_LIMIT_MAX
|| i
->memory_swap_max
!= CGROUP_LIMIT_MAX
||
4231 i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4232 const char *prefix
= "";
4235 if (i
->memory_low
> 0) {
4236 printf("%slow: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_low
));
4239 if (i
->memory_high
!= CGROUP_LIMIT_MAX
) {
4240 printf("%shigh: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_high
));
4243 if (i
->memory_max
!= CGROUP_LIMIT_MAX
) {
4244 printf("%smax: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_max
));
4247 if (i
->memory_swap_max
!= CGROUP_LIMIT_MAX
) {
4248 printf("%sswap max: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_swap_max
));
4251 if (i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4252 printf("%slimit: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
4260 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
4261 char buf
[FORMAT_TIMESPAN_MAX
];
4262 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
4265 if (i
->control_group
) {
4266 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4267 static const char prefix
[] = " ";
4270 printf(" CGroup: %s\n", i
->control_group
);
4273 if (c
> sizeof(prefix
) - 1)
4274 c
-= sizeof(prefix
) - 1;
4278 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
4283 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4285 if (i
->main_pid
> 0)
4286 extra
[k
++] = i
->main_pid
;
4288 if (i
->control_pid
> 0)
4289 extra
[k
++] = i
->control_pid
;
4291 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
4293 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
4296 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
4297 show_journal_by_unit(
4302 i
->inactive_exit_timestamp_monotonic
,
4305 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
4306 SD_JOURNAL_LOCAL_ONLY
,
4307 arg_scope
== UNIT_FILE_SYSTEM
,
4310 if (i
->need_daemon_reload
)
4311 warn_unit_file_changed(i
->id
);
4314 static void show_unit_help(UnitStatusInfo
*i
) {
4319 if (!i
->documentation
) {
4320 log_info("Documentation for %s not known.", i
->id
);
4324 STRV_FOREACH(p
, i
->documentation
)
4325 if (startswith(*p
, "man:"))
4326 show_man_page(*p
+ 4, false);
4328 log_info("Can't show: %s", *p
);
4331 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
4338 switch (contents
[0]) {
4340 case SD_BUS_TYPE_STRING
: {
4343 r
= sd_bus_message_read(m
, "s", &s
);
4345 return bus_log_parse_error(r
);
4348 if (streq(name
, "Id"))
4350 else if (streq(name
, "LoadState"))
4352 else if (streq(name
, "ActiveState"))
4353 i
->active_state
= s
;
4354 else if (streq(name
, "SubState"))
4356 else if (streq(name
, "Description"))
4358 else if (streq(name
, "FragmentPath"))
4359 i
->fragment_path
= s
;
4360 else if (streq(name
, "SourcePath"))
4363 else if (streq(name
, "DefaultControlGroup")) {
4365 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
4367 i
->control_group
= e
;
4370 else if (streq(name
, "ControlGroup"))
4371 i
->control_group
= s
;
4372 else if (streq(name
, "StatusText"))
4374 else if (streq(name
, "PIDFile"))
4376 else if (streq(name
, "SysFSPath"))
4378 else if (streq(name
, "Where"))
4380 else if (streq(name
, "What"))
4382 else if (streq(name
, "Following"))
4384 else if (streq(name
, "UnitFileState"))
4385 i
->unit_file_state
= s
;
4386 else if (streq(name
, "UnitFilePreset"))
4387 i
->unit_file_preset
= s
;
4388 else if (streq(name
, "Result"))
4395 case SD_BUS_TYPE_BOOLEAN
: {
4398 r
= sd_bus_message_read(m
, "b", &b
);
4400 return bus_log_parse_error(r
);
4402 if (streq(name
, "Accept"))
4404 else if (streq(name
, "NeedDaemonReload"))
4405 i
->need_daemon_reload
= b
;
4406 else if (streq(name
, "ConditionResult"))
4407 i
->condition_result
= b
;
4408 else if (streq(name
, "AssertResult"))
4409 i
->assert_result
= b
;
4410 else if (streq(name
, "Transient"))
4416 case SD_BUS_TYPE_UINT32
: {
4419 r
= sd_bus_message_read(m
, "u", &u
);
4421 return bus_log_parse_error(r
);
4423 if (streq(name
, "MainPID")) {
4425 i
->main_pid
= (pid_t
) u
;
4428 } else if (streq(name
, "ControlPID"))
4429 i
->control_pid
= (pid_t
) u
;
4430 else if (streq(name
, "ExecMainPID")) {
4432 i
->main_pid
= (pid_t
) u
;
4433 } else if (streq(name
, "NAccepted"))
4435 else if (streq(name
, "NConnections"))
4436 i
->n_connections
= u
;
4441 case SD_BUS_TYPE_INT32
: {
4444 r
= sd_bus_message_read(m
, "i", &j
);
4446 return bus_log_parse_error(r
);
4448 if (streq(name
, "ExecMainCode"))
4449 i
->exit_code
= (int) j
;
4450 else if (streq(name
, "ExecMainStatus"))
4451 i
->exit_status
= (int) j
;
4452 else if (streq(name
, "StatusErrno"))
4453 i
->status_errno
= (int) j
;
4458 case SD_BUS_TYPE_UINT64
: {
4461 r
= sd_bus_message_read(m
, "t", &u
);
4463 return bus_log_parse_error(r
);
4465 if (streq(name
, "ExecMainStartTimestamp"))
4466 i
->start_timestamp
= (usec_t
) u
;
4467 else if (streq(name
, "ExecMainExitTimestamp"))
4468 i
->exit_timestamp
= (usec_t
) u
;
4469 else if (streq(name
, "ActiveEnterTimestamp"))
4470 i
->active_enter_timestamp
= (usec_t
) u
;
4471 else if (streq(name
, "InactiveEnterTimestamp"))
4472 i
->inactive_enter_timestamp
= (usec_t
) u
;
4473 else if (streq(name
, "InactiveExitTimestamp"))
4474 i
->inactive_exit_timestamp
= (usec_t
) u
;
4475 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4476 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4477 else if (streq(name
, "ActiveExitTimestamp"))
4478 i
->active_exit_timestamp
= (usec_t
) u
;
4479 else if (streq(name
, "ConditionTimestamp"))
4480 i
->condition_timestamp
= (usec_t
) u
;
4481 else if (streq(name
, "AssertTimestamp"))
4482 i
->assert_timestamp
= (usec_t
) u
;
4483 else if (streq(name
, "MemoryCurrent"))
4484 i
->memory_current
= u
;
4485 else if (streq(name
, "MemoryLow"))
4487 else if (streq(name
, "MemoryHigh"))
4489 else if (streq(name
, "MemoryMax"))
4491 else if (streq(name
, "MemorySwapMax"))
4492 i
->memory_swap_max
= u
;
4493 else if (streq(name
, "MemoryLimit"))
4494 i
->memory_limit
= u
;
4495 else if (streq(name
, "TasksCurrent"))
4496 i
->tasks_current
= u
;
4497 else if (streq(name
, "TasksMax"))
4499 else if (streq(name
, "CPUUsageNSec"))
4500 i
->cpu_usage_nsec
= u
;
4501 else if (streq(name
, "NextElapseUSecMonotonic"))
4502 i
->next_elapse_monotonic
= u
;
4503 else if (streq(name
, "NextElapseUSecRealtime"))
4504 i
->next_elapse_real
= u
;
4505 else if (streq(name
, "IPIngressBytes"))
4506 i
->ip_ingress_bytes
= u
;
4507 else if (streq(name
, "IPEgressBytes"))
4508 i
->ip_egress_bytes
= u
;
4513 case SD_BUS_TYPE_ARRAY
:
4515 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4516 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4518 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4520 return bus_log_parse_error(r
);
4522 info
= new0(ExecStatusInfo
, 1);
4526 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4528 info
->name
= strdup(name
);
4532 LIST_PREPEND(exec
, i
->exec
, info
);
4534 info
= new0(ExecStatusInfo
, 1);
4540 return bus_log_parse_error(r
);
4542 r
= sd_bus_message_exit_container(m
);
4544 return bus_log_parse_error(r
);
4548 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4549 const char *type
, *path
;
4551 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4553 return bus_log_parse_error(r
);
4555 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4557 r
= strv_extend(&i
->listen
, type
);
4561 r
= strv_extend(&i
->listen
, path
);
4566 return bus_log_parse_error(r
);
4568 r
= sd_bus_message_exit_container(m
);
4570 return bus_log_parse_error(r
);
4574 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4576 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4578 return bus_log_parse_error(r
);
4580 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4582 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4584 return bus_log_parse_error(r
);
4586 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4587 const char *cond
, *param
;
4588 int trigger
, negate
;
4591 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4593 return bus_log_parse_error(r
);
4595 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4596 _cleanup_(unit_condition_freep
) UnitCondition
*c
= NULL
;
4598 log_debug("%s trigger=%d negate=%d %s →%d", cond
, trigger
, negate
, param
, state
);
4600 c
= new0(UnitCondition
, 1);
4604 c
->name
= strdup(cond
);
4605 c
->param
= strdup(param
);
4606 if (!c
->name
|| !c
->param
)
4609 c
->trigger
= trigger
;
4611 c
->tristate
= state
;
4613 LIST_PREPEND(conditions
, i
->conditions
, c
);
4617 return bus_log_parse_error(r
);
4619 r
= sd_bus_message_exit_container(m
);
4621 return bus_log_parse_error(r
);
4623 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4624 const char *cond
, *param
;
4625 int trigger
, negate
;
4628 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4630 return bus_log_parse_error(r
);
4632 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4633 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4634 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4635 i
->failed_assert
= cond
;
4636 i
->failed_assert_trigger
= trigger
;
4637 i
->failed_assert_negate
= negate
;
4638 i
->failed_assert_parameter
= param
;
4642 return bus_log_parse_error(r
);
4644 r
= sd_bus_message_exit_container(m
);
4646 return bus_log_parse_error(r
);
4653 case SD_BUS_TYPE_STRUCT_BEGIN
:
4655 if (streq(name
, "LoadError")) {
4656 const char *n
, *message
;
4658 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4660 return bus_log_parse_error(r
);
4662 if (!isempty(message
))
4663 i
->load_error
= message
;
4676 r
= sd_bus_message_skip(m
, contents
);
4678 return bus_log_parse_error(r
);
4683 #define print_prop(name, fmt, ...) \
4686 printf(fmt "\n", __VA_ARGS__); \
4688 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4691 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4697 /* This is a low-level property printer, see
4698 * print_status_info() for the nicer output */
4700 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4701 /* skip what we didn't read */
4702 r
= sd_bus_message_skip(m
, contents
);
4706 switch (contents
[0]) {
4708 case SD_BUS_TYPE_STRUCT_BEGIN
:
4710 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4713 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4715 return bus_log_parse_error(r
);
4718 print_prop(name
, "%"PRIu32
, u
);
4720 print_prop(name
, "%s", "");
4724 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4727 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4729 return bus_log_parse_error(r
);
4731 if (arg_all
|| !isempty(s
))
4732 print_prop(name
, "%s", s
);
4736 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4737 const char *a
= NULL
, *b
= NULL
;
4739 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4741 return bus_log_parse_error(r
);
4743 if (arg_all
|| !isempty(a
) || !isempty(b
))
4744 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4747 } else if (streq_ptr(name
, "SystemCallFilter")) {
4748 _cleanup_strv_free_
char **l
= NULL
;
4751 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4753 return bus_log_parse_error(r
);
4755 r
= sd_bus_message_read(m
, "b", &whitelist
);
4757 return bus_log_parse_error(r
);
4759 r
= sd_bus_message_read_strv(m
, &l
);
4761 return bus_log_parse_error(r
);
4763 r
= sd_bus_message_exit_container(m
);
4765 return bus_log_parse_error(r
);
4767 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4772 fputs(name
, stdout
);
4779 STRV_FOREACH(i
, l
) {
4787 fputc('\n', stdout
);
4795 case SD_BUS_TYPE_ARRAY
:
4797 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4801 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4803 return bus_log_parse_error(r
);
4805 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4806 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path
, yes_no(ignore
));
4809 return bus_log_parse_error(r
);
4811 r
= sd_bus_message_exit_container(m
);
4813 return bus_log_parse_error(r
);
4817 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4818 const char *type
, *path
;
4820 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4822 return bus_log_parse_error(r
);
4824 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4825 print_prop(type
, "%s", path
);
4827 return bus_log_parse_error(r
);
4829 r
= sd_bus_message_exit_container(m
);
4831 return bus_log_parse_error(r
);
4835 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4836 const char *type
, *path
;
4838 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4840 return bus_log_parse_error(r
);
4842 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4846 printf("Listen%s=%s\n", type
, path
);
4848 return bus_log_parse_error(r
);
4850 r
= sd_bus_message_exit_container(m
);
4852 return bus_log_parse_error(r
);
4856 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4858 uint64_t value
, next_elapse
;
4860 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4862 return bus_log_parse_error(r
);
4864 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4865 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4867 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4868 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4869 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4872 return bus_log_parse_error(r
);
4874 r
= sd_bus_message_exit_container(m
);
4876 return bus_log_parse_error(r
);
4880 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4881 ExecStatusInfo info
= {};
4883 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4885 return bus_log_parse_error(r
);
4887 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4888 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4889 _cleanup_free_
char *tt
;
4891 tt
= strv_join(info
.argv
, " ");
4894 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4897 yes_no(info
.ignore
),
4898 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4899 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4901 sigchld_code_to_string(info
.code
),
4903 info
.code
== CLD_EXITED
? "" : "/",
4904 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4907 strv_free(info
.argv
);
4911 r
= sd_bus_message_exit_container(m
);
4913 return bus_log_parse_error(r
);
4917 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4918 const char *path
, *rwm
;
4920 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4922 return bus_log_parse_error(r
);
4924 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4925 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4927 return bus_log_parse_error(r
);
4929 r
= sd_bus_message_exit_container(m
);
4931 return bus_log_parse_error(r
);
4935 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4936 STR_IN_SET(name
, "IODeviceWeight", "BlockIODeviceWeight")) {
4940 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4942 return bus_log_parse_error(r
);
4944 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4945 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4947 return bus_log_parse_error(r
);
4949 r
= sd_bus_message_exit_container(m
);
4951 return bus_log_parse_error(r
);
4955 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4956 (cgroup_io_limit_type_from_string(name
) >= 0 ||
4957 STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
4961 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4963 return bus_log_parse_error(r
);
4965 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4966 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4968 return bus_log_parse_error(r
);
4970 r
= sd_bus_message_exit_container(m
);
4972 return bus_log_parse_error(r
);
4980 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4982 return bus_log_parse_error(r
);
4985 r
= sd_bus_message_skip(m
, contents
);
4987 return bus_log_parse_error(r
);
4990 printf("%s=[unprintable]\n", name
);
4996 static int show_one(
5001 bool show_properties
,
5005 static const struct bus_properties_map property_map
[] = {
5006 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
5007 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
) },
5011 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5012 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5013 _cleanup_set_free_ Set
*found_properties
= NULL
;
5014 _cleanup_(unit_status_info_free
) UnitStatusInfo info
= {
5015 .memory_current
= (uint64_t) -1,
5016 .memory_high
= CGROUP_LIMIT_MAX
,
5017 .memory_max
= CGROUP_LIMIT_MAX
,
5018 .memory_swap_max
= CGROUP_LIMIT_MAX
,
5019 .memory_limit
= (uint64_t) -1,
5020 .cpu_usage_nsec
= (uint64_t) -1,
5021 .tasks_current
= (uint64_t) -1,
5022 .tasks_max
= (uint64_t) -1,
5023 .ip_ingress_bytes
= (uint64_t) -1,
5024 .ip_egress_bytes
= (uint64_t) -1,
5031 log_debug("Showing one %s", path
);
5033 r
= sd_bus_call_method(
5035 "org.freedesktop.systemd1",
5037 "org.freedesktop.DBus.Properties",
5043 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
5046 r
= bus_message_map_all_properties(reply
, property_map
, &error
, &info
);
5048 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
5050 if (streq_ptr(info
.load_state
, "not-found") && streq_ptr(info
.active_state
, "inactive")) {
5051 log_full(streq(verb
, "status") ? LOG_ERR
: LOG_DEBUG
,
5052 "Unit %s could not be found.", unit
);
5054 if (streq(verb
, "status"))
5055 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
;
5057 if (!streq(verb
, "show"))
5061 r
= sd_bus_message_rewind(reply
, true);
5063 return log_error_errno(r
, "Failed to rewind: %s", bus_error_message(&error
, r
));
5066 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
5068 return bus_log_parse_error(r
);
5075 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
5076 const char *name
, *contents
;
5078 r
= sd_bus_message_read(reply
, "s", &name
);
5080 return bus_log_parse_error(r
);
5082 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
5084 return bus_log_parse_error(r
);
5086 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
5088 return bus_log_parse_error(r
);
5090 if (show_properties
) {
5091 r
= set_ensure_allocated(&found_properties
, &string_hash_ops
);
5095 r
= set_put(found_properties
, name
);
5096 if (r
< 0 && r
!= EEXIST
)
5099 r
= print_property(name
, reply
, contents
);
5101 r
= status_property(name
, reply
, &info
, contents
);
5105 r
= sd_bus_message_exit_container(reply
);
5107 return bus_log_parse_error(r
);
5109 r
= sd_bus_message_exit_container(reply
);
5111 return bus_log_parse_error(r
);
5114 return bus_log_parse_error(r
);
5116 r
= sd_bus_message_exit_container(reply
);
5118 return bus_log_parse_error(r
);
5121 if (show_properties
) {
5124 STRV_FOREACH(pp
, arg_properties
)
5125 if (!set_contains(found_properties
, *pp
))
5126 log_debug("Property %s does not exist.", *pp
);
5128 } else if (streq(verb
, "help"))
5129 show_unit_help(&info
);
5130 else if (streq(verb
, "status")) {
5131 print_status_info(bus
, &info
, ellipsized
);
5133 if (info
.active_state
&& !STR_IN_SET(info
.active_state
, "active", "reloading"))
5134 r
= EXIT_PROGRAM_NOT_RUNNING
;
5136 r
= EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
;
5142 static int get_unit_dbus_path_by_pid(
5147 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5148 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5152 r
= sd_bus_call_method(
5154 "org.freedesktop.systemd1",
5155 "/org/freedesktop/systemd1",
5156 "org.freedesktop.systemd1.Manager",
5162 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
5164 r
= sd_bus_message_read(reply
, "o", &u
);
5166 return bus_log_parse_error(r
);
5176 static int show_all(
5179 bool show_properties
,
5183 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5184 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
5189 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
5193 pager_open(arg_no_pager
, false);
5197 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
5199 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
5200 _cleanup_free_
char *p
= NULL
;
5202 p
= unit_dbus_path_from_name(u
->id
);
5206 r
= show_one(verb
, bus
, p
, u
->id
, show_properties
, new_line
, ellipsized
);
5209 else if (r
> 0 && ret
== 0)
5216 static int show_system_status(sd_bus
*bus
) {
5217 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
5218 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5219 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
5220 _cleanup_free_
char *hn
= NULL
;
5221 const char *on
, *off
;
5224 hn
= gethostname_malloc();
5228 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &error
, &mi
);
5230 return log_error_errno(r
, "Failed to read server status: %s", bus_error_message(&error
, r
));
5232 if (streq_ptr(mi
.state
, "degraded")) {
5233 on
= ansi_highlight_red();
5234 off
= ansi_normal();
5235 } else if (streq_ptr(mi
.state
, "running")) {
5236 on
= ansi_highlight_green();
5237 off
= ansi_normal();
5239 on
= ansi_highlight_yellow();
5240 off
= ansi_normal();
5243 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
5245 printf(" State: %s%s%s\n",
5246 on
, strna(mi
.state
), off
);
5248 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
5249 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
5251 printf(" Since: %s; %s\n",
5252 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
5253 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
5255 printf(" CGroup: %s\n", mi
.control_group
?: "/");
5256 if (IN_SET(arg_transport
,
5257 BUS_TRANSPORT_LOCAL
,
5258 BUS_TRANSPORT_MACHINE
)) {
5259 static const char prefix
[] = " ";
5263 if (c
> sizeof(prefix
) - 1)
5264 c
-= sizeof(prefix
) - 1;
5268 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
5274 static int show(int argc
, char *argv
[], void *userdata
) {
5275 bool show_properties
, show_status
, show_help
, new_line
= false;
5276 bool ellipsized
= false;
5282 show_properties
= streq(argv
[0], "show");
5283 show_status
= streq(argv
[0], "status");
5284 show_help
= streq(argv
[0], "help");
5286 if (show_help
&& argc
<= 1) {
5287 log_error("This command expects one or more unit names. Did you mean --help?");
5291 r
= acquire_bus(BUS_MANAGER
, &bus
);
5295 pager_open(arg_no_pager
, false);
5298 /* Increase max number of open files to 16K if we can, we
5299 * might needs this when browsing journal files, which might
5300 * be split up into many files. */
5301 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
5303 /* If no argument is specified inspect the manager itself */
5304 if (show_properties
&& argc
<= 1)
5305 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", NULL
, show_properties
, &new_line
, &ellipsized
);
5307 if (show_status
&& argc
<= 1) {
5309 show_system_status(bus
);
5313 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
5315 _cleanup_free_
char **patterns
= NULL
;
5318 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
5319 _cleanup_free_
char *path
= NULL
, *unit
= NULL
;
5322 if (safe_atou32(*name
, &id
) < 0) {
5323 if (strv_push(&patterns
, *name
) < 0)
5327 } else if (show_properties
) {
5328 /* Interpret as job id */
5329 if (asprintf(&path
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
5333 /* Interpret as PID */
5334 r
= get_unit_dbus_path_by_pid(bus
, id
, &path
);
5340 r
= unit_name_from_dbus_path(path
, &unit
);
5345 r
= show_one(argv
[0], bus
, path
, unit
, show_properties
, &new_line
, &ellipsized
);
5348 else if (r
> 0 && ret
== 0)
5352 if (!strv_isempty(patterns
)) {
5353 _cleanup_strv_free_
char **names
= NULL
;
5355 r
= expand_names(bus
, patterns
, NULL
, &names
);
5357 return log_error_errno(r
, "Failed to expand names: %m");
5359 STRV_FOREACH(name
, names
) {
5360 _cleanup_free_
char *path
;
5362 path
= unit_dbus_path_from_name(*name
);
5366 r
= show_one(argv
[0], bus
, path
, *name
, show_properties
, &new_line
, &ellipsized
);
5369 if (r
> 0 && ret
== 0)
5375 if (ellipsized
&& !arg_quiet
)
5376 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5381 static int cat_file(const char *filename
, bool newline
) {
5382 _cleanup_close_
int fd
;
5384 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
5388 printf("%s%s# %s%s\n",
5389 newline
? "\n" : "",
5390 ansi_highlight_blue(),
5395 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, 0);
5398 static int cat(int argc
, char *argv
[], void *userdata
) {
5399 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5400 _cleanup_strv_free_
char **names
= NULL
;
5406 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5407 log_error("Cannot remotely cat units.");
5411 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
5413 return log_error_errno(r
, "Failed to determine unit paths: %m");
5415 r
= acquire_bus(BUS_MANAGER
, &bus
);
5419 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5421 return log_error_errno(r
, "Failed to expand names: %m");
5423 pager_open(arg_no_pager
, false);
5425 STRV_FOREACH(name
, names
) {
5426 _cleanup_free_
char *fragment_path
= NULL
;
5427 _cleanup_strv_free_
char **dropin_paths
= NULL
;
5430 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
5441 if (need_daemon_reload(bus
, *name
) > 0) /* ignore errors (<0), this is informational output */
5443 "%s# Warning: %s changed on disk, the version systemd has loaded is outdated.\n"
5444 "%s# This output shows the current version of the unit's original fragment and drop-in files.\n"
5445 "%s# If fragments or drop-ins were added or removed, they are not properly reflected in this output.\n"
5446 "%s# Run 'systemctl%s daemon-reload' to reload units.%s\n",
5447 ansi_highlight_red(),
5449 ansi_highlight_red(),
5450 ansi_highlight_red(),
5451 ansi_highlight_red(),
5452 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
5455 if (fragment_path
) {
5456 r
= cat_file(fragment_path
, false);
5458 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
5461 STRV_FOREACH(path
, dropin_paths
) {
5462 r
= cat_file(*path
, path
== dropin_paths
);
5464 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
5471 static int set_property(int argc
, char *argv
[], void *userdata
) {
5472 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5473 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5474 _cleanup_free_
char *n
= NULL
;
5478 r
= acquire_bus(BUS_MANAGER
, &bus
);
5482 polkit_agent_open_maybe();
5484 r
= sd_bus_message_new_method_call(
5487 "org.freedesktop.systemd1",
5488 "/org/freedesktop/systemd1",
5489 "org.freedesktop.systemd1.Manager",
5490 "SetUnitProperties");
5492 return bus_log_create_error(r
);
5494 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
5496 return log_error_errno(r
, "Failed to mangle unit name: %m");
5498 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
5500 return bus_log_create_error(r
);
5502 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
5504 return bus_log_create_error(r
);
5506 r
= bus_append_unit_property_assignment_many(m
, strv_skip(argv
, 2));
5510 r
= sd_bus_message_close_container(m
);
5512 return bus_log_create_error(r
);
5514 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5516 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
5521 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5522 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5523 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5528 r
= acquire_bus(BUS_MANAGER
, &bus
);
5532 polkit_agent_open_maybe();
5534 switch (arg_action
) {
5541 method
= "Reexecute";
5544 case ACTION_SYSTEMCTL
:
5545 method
= streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5546 /* "daemon-reload" */ "Reload";
5550 assert_not_reached("Unexpected action");
5553 r
= sd_bus_message_new_method_call(
5556 "org.freedesktop.systemd1",
5557 "/org/freedesktop/systemd1",
5558 "org.freedesktop.systemd1.Manager",
5561 return bus_log_create_error(r
);
5563 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5564 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5565 * their timeout, and for everything else there's the same time budget in place. */
5567 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
5569 /* On reexecution, we expect a disconnect, not a reply */
5570 if (IN_SET(r
, -ETIMEDOUT
, -ECONNRESET
) && streq(method
, "Reexecute"))
5573 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5574 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5576 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5577 * old ways of doing things, hence don't log any error in that case here. */
5579 return r
< 0 ? r
: 0;
5582 static int trivial_method(int argc
, char *argv
[], void *userdata
) {
5583 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5588 r
= acquire_bus(BUS_MANAGER
, &bus
);
5592 polkit_agent_open_maybe();
5595 streq(argv
[0], "clear-jobs") ||
5596 streq(argv
[0], "cancel") ? "ClearJobs" :
5597 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5598 streq(argv
[0], "halt") ? "Halt" :
5599 streq(argv
[0], "reboot") ? "Reboot" :
5600 streq(argv
[0], "kexec") ? "KExec" :
5601 streq(argv
[0], "exit") ? "Exit" :
5602 /* poweroff */ "PowerOff";
5604 r
= sd_bus_call_method(
5606 "org.freedesktop.systemd1",
5607 "/org/freedesktop/systemd1",
5608 "org.freedesktop.systemd1.Manager",
5613 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5614 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5616 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5617 * old ways of doing things, hence don't log any error in that case here. */
5619 return r
< 0 ? r
: 0;
5622 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5623 _cleanup_strv_free_
char **names
= NULL
;
5629 return trivial_method(argc
, argv
, userdata
);
5631 r
= acquire_bus(BUS_MANAGER
, &bus
);
5635 polkit_agent_open_maybe();
5637 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5639 return log_error_errno(r
, "Failed to expand names: %m");
5641 STRV_FOREACH(name
, names
) {
5642 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5644 q
= sd_bus_call_method(
5646 "org.freedesktop.systemd1",
5647 "/org/freedesktop/systemd1",
5648 "org.freedesktop.systemd1.Manager",
5654 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5663 static int print_variable(const char *s
) {
5665 _cleanup_free_
char *esc
= NULL
;
5667 sep
= strchr(s
, '=');
5669 log_error("Invalid environment block");
5673 esc
= shell_maybe_quote(sep
+ 1, ESCAPE_POSIX
);
5677 printf("%.*s=%s\n", (int)(sep
-s
), s
, esc
);
5681 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5682 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5683 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5688 r
= acquire_bus(BUS_MANAGER
, &bus
);
5692 pager_open(arg_no_pager
, false);
5694 r
= sd_bus_get_property(
5696 "org.freedesktop.systemd1",
5697 "/org/freedesktop/systemd1",
5698 "org.freedesktop.systemd1.Manager",
5704 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5706 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5708 return bus_log_parse_error(r
);
5710 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0) {
5711 r
= print_variable(text
);
5716 return bus_log_parse_error(r
);
5718 r
= sd_bus_message_exit_container(reply
);
5720 return bus_log_parse_error(r
);
5725 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5726 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5727 _cleanup_free_
char *cmdline_init
= NULL
;
5728 const char *root
, *init
;
5732 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5733 log_error("Cannot switch root remotely.");
5737 if (argc
< 2 || argc
> 3) {
5738 log_error("Wrong number of arguments.");
5747 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5748 "init", &cmdline_init
,
5751 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5753 init
= cmdline_init
;
5756 init
= empty_to_null(init
);
5758 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5760 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5761 root_init_path
= strjoina(root
, "/", init
);
5763 /* If the passed init is actually the same as the
5764 * systemd binary, then let's suppress it. */
5765 if (files_same(root_init_path
, root_systemd_path
, 0) > 0)
5769 /* Instruct PID1 to exclude us from its killing spree applied during
5770 * the transition. Otherwise we would exit with a failure status even
5771 * though the switch to the new root has succeed. */
5772 argv_cmdline
[0] = '@';
5774 r
= acquire_bus(BUS_MANAGER
, &bus
);
5778 /* If we are slow to exit after the root switch, the new systemd instance
5779 * will send us a signal to terminate. Just ignore it and exit normally.
5780 * This way the unit does not end up as failed.
5782 r
= ignore_signals(SIGTERM
, -1);
5784 log_warning_errno(r
, "Failed to change disposition of SIGTERM to ignore: %m");
5786 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5788 r
= sd_bus_call_method(
5790 "org.freedesktop.systemd1",
5791 "/org/freedesktop/systemd1",
5792 "org.freedesktop.systemd1.Manager",
5798 (void) default_signals(SIGTERM
, -1);
5800 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5806 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5807 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5808 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5816 r
= acquire_bus(BUS_MANAGER
, &bus
);
5820 polkit_agent_open_maybe();
5822 method
= streq(argv
[0], "set-environment")
5824 : "UnsetEnvironment";
5826 r
= sd_bus_message_new_method_call(
5829 "org.freedesktop.systemd1",
5830 "/org/freedesktop/systemd1",
5831 "org.freedesktop.systemd1.Manager",
5834 return bus_log_create_error(r
);
5836 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5838 return bus_log_create_error(r
);
5840 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5842 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5847 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5848 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5849 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5853 r
= acquire_bus(BUS_MANAGER
, &bus
);
5857 polkit_agent_open_maybe();
5859 r
= sd_bus_message_new_method_call(
5862 "org.freedesktop.systemd1",
5863 "/org/freedesktop/systemd1",
5864 "org.freedesktop.systemd1.Manager",
5867 return bus_log_create_error(r
);
5870 r
= sd_bus_message_append_strv(m
, environ
);
5874 r
= sd_bus_message_open_container(m
, 'a', "s");
5876 return bus_log_create_error(r
);
5878 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5880 if (!env_name_is_valid(*a
)) {
5881 log_error("Not a valid environment variable name: %s", *a
);
5885 STRV_FOREACH(b
, environ
) {
5888 eq
= startswith(*b
, *a
);
5889 if (eq
&& *eq
== '=') {
5891 r
= sd_bus_message_append(m
, "s", *b
);
5893 return bus_log_create_error(r
);
5900 r
= sd_bus_message_close_container(m
);
5903 return bus_log_create_error(r
);
5905 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5907 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5912 static int enable_sysv_units(const char *verb
, char **args
) {
5915 #if HAVE_SYSV_COMPAT
5916 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5919 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5921 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5924 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5927 if (!STR_IN_SET(verb
,
5933 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5940 const char *argv
[] = {
5941 ROOTLIBEXECDIR
"/systemd-sysv-install",
5948 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5949 bool found_native
= false, found_sysv
;
5958 if (!endswith(name
, ".service"))
5961 if (path_is_absolute(name
))
5964 j
= unit_file_exists(arg_scope
, &paths
, name
);
5965 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5966 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5967 found_native
= j
!= 0;
5969 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5970 * prefer the native unit */
5971 if (found_native
&& streq(verb
, "is-enabled"))
5974 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5978 p
[strlen(p
) - strlen(".service")] = 0;
5979 found_sysv
= access(p
, F_OK
) >= 0;
5985 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5987 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5990 if (!isempty(arg_root
))
5991 argv
[c
++] = q
= strappend("--root=", arg_root
);
5994 argv
[c
++] = basename(p
);
5997 l
= strv_join((char**)argv
, " ");
6002 log_info("Executing: %s", l
);
6006 return log_error_errno(errno
, "Failed to fork: %m");
6007 else if (pid
== 0) {
6010 (void) reset_all_signal_handlers();
6011 (void) reset_signal_mask();
6013 execv(argv
[0], (char**) argv
);
6014 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
6015 _exit(EXIT_FAILURE
);
6018 j
= wait_for_terminate(pid
, &status
);
6020 return log_error_errno(j
, "Failed to wait for child: %m");
6022 if (status
.si_code
== CLD_EXITED
) {
6023 if (streq(verb
, "is-enabled")) {
6024 if (status
.si_status
== 0) {
6033 } else if (status
.si_status
!= 0)
6034 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
6036 log_error("Unexpected waitid() result.");
6043 /* Remove this entry, so that we don't try enabling it as native unit */
6046 assert(args
[f
] == name
);
6047 strv_remove(args
, name
);
6054 static int mangle_names(char **original_names
, char ***mangled_names
) {
6055 char **i
, **l
, **name
;
6058 l
= i
= new(char*, strv_length(original_names
) + 1);
6062 STRV_FOREACH(name
, original_names
) {
6064 /* When enabling units qualified path names are OK,
6065 * too, hence allow them explicitly. */
6067 if (is_path(*name
)) {
6074 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
6078 return log_error_errno(r
, "Failed to mangle unit name: %m");
6091 static int normalize_filenames(char **names
) {
6095 STRV_FOREACH(u
, names
)
6096 if (!path_is_absolute(*u
)) {
6097 char* normalized_path
;
6099 if (!isempty(arg_root
)) {
6100 log_error("Non-absolute paths are not allowed when --root is used: %s", *u
);
6104 if (!strchr(*u
,'/')) {
6105 log_error("Link argument does contain at least one directory separator: %s", *u
);
6109 r
= path_make_absolute_cwd(*u
, &normalized_path
);
6113 free_and_replace(*u
, normalized_path
);
6119 static int normalize_names(char **names
, bool warn_if_path
) {
6121 bool was_path
= false;
6123 STRV_FOREACH(u
, names
) {
6129 r
= free_and_strdup(u
, basename(*u
));
6131 return log_error_errno(r
, "Failed to normalize unit file path: %m");
6136 if (warn_if_path
&& was_path
)
6137 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
6142 static int unit_exists(LookupPaths
*lp
, const char *unit
) {
6143 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6144 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6145 _cleanup_free_
char *path
= NULL
;
6146 static const struct bus_properties_map property_map
[] = {
6147 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
6148 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
)},
6151 UnitStatusInfo info
= {};
6155 if (unit_name_is_valid(unit
, UNIT_NAME_TEMPLATE
))
6156 return unit_find_template_path(unit
, lp
, NULL
, NULL
);
6158 path
= unit_dbus_path_from_name(unit
);
6162 r
= acquire_bus(BUS_MANAGER
, &bus
);
6166 r
= sd_bus_call_method(
6168 "org.freedesktop.systemd1",
6170 "org.freedesktop.DBus.Properties",
6176 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
6178 r
= bus_message_map_all_properties(reply
, property_map
, &error
, &info
);
6180 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
6182 return !streq_ptr(info
.load_state
, "not-found") || !streq_ptr(info
.active_state
, "inactive");
6185 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
6186 _cleanup_strv_free_
char **names
= NULL
;
6187 const char *verb
= argv
[0];
6188 UnitFileChange
*changes
= NULL
;
6189 unsigned n_changes
= 0;
6190 int carries_install_info
= -1;
6191 bool ignore_carries_install_info
= arg_quiet
;
6197 r
= mangle_names(strv_skip(argv
, 1), &names
);
6201 r
= enable_sysv_units(verb
, names
);
6205 /* If the operation was fully executed by the SysV compat, let's finish early */
6206 if (strv_isempty(names
)) {
6207 if (arg_no_reload
|| install_client_side())
6209 return daemon_reload(argc
, argv
, userdata
);
6212 if (streq(verb
, "disable")) {
6213 r
= normalize_names(names
, true);
6218 if (streq(verb
, "link")) {
6219 r
= normalize_filenames(names
);
6224 if (install_client_side()) {
6225 UnitFileFlags flags
;
6227 flags
= args_to_flags();
6228 if (streq(verb
, "enable")) {
6229 r
= unit_file_enable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6230 carries_install_info
= r
;
6231 } else if (streq(verb
, "disable"))
6232 r
= unit_file_disable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6233 else if (streq(verb
, "reenable")) {
6234 r
= unit_file_reenable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6235 carries_install_info
= r
;
6236 } else if (streq(verb
, "link"))
6237 r
= unit_file_link(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6238 else if (streq(verb
, "preset")) {
6239 r
= unit_file_preset(arg_scope
, flags
, arg_root
, names
, arg_preset_mode
, &changes
, &n_changes
);
6240 } else if (streq(verb
, "mask"))
6241 r
= unit_file_mask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6242 else if (streq(verb
, "unmask"))
6243 r
= unit_file_unmask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6244 else if (streq(verb
, "revert"))
6245 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
6247 assert_not_reached("Unknown verb");
6249 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
6254 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6255 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6256 bool expect_carries_install_info
= false;
6257 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
6261 if (STR_IN_SET(verb
, "mask", "unmask")) {
6263 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6265 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6269 STRV_FOREACH(name
, names
) {
6270 r
= unit_exists(&lp
, *name
);
6274 log_notice("Unit %s does not exist, proceeding anyway.", *names
);
6278 r
= acquire_bus(BUS_MANAGER
, &bus
);
6282 polkit_agent_open_maybe();
6284 if (streq(verb
, "enable")) {
6285 method
= "EnableUnitFiles";
6286 expect_carries_install_info
= true;
6287 } else if (streq(verb
, "disable")) {
6288 method
= "DisableUnitFiles";
6290 } else if (streq(verb
, "reenable")) {
6291 method
= "ReenableUnitFiles";
6292 expect_carries_install_info
= true;
6293 } else if (streq(verb
, "link"))
6294 method
= "LinkUnitFiles";
6295 else if (streq(verb
, "preset")) {
6297 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
6298 method
= "PresetUnitFilesWithMode";
6299 send_preset_mode
= true;
6301 method
= "PresetUnitFiles";
6303 expect_carries_install_info
= true;
6304 ignore_carries_install_info
= true;
6305 } else if (streq(verb
, "mask"))
6306 method
= "MaskUnitFiles";
6307 else if (streq(verb
, "unmask")) {
6308 method
= "UnmaskUnitFiles";
6310 } else if (streq(verb
, "revert")) {
6311 method
= "RevertUnitFiles";
6312 send_runtime
= send_force
= false;
6314 assert_not_reached("Unknown verb");
6316 r
= sd_bus_message_new_method_call(
6319 "org.freedesktop.systemd1",
6320 "/org/freedesktop/systemd1",
6321 "org.freedesktop.systemd1.Manager",
6324 return bus_log_create_error(r
);
6326 r
= sd_bus_message_append_strv(m
, names
);
6328 return bus_log_create_error(r
);
6330 if (send_preset_mode
) {
6331 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
6333 return bus_log_create_error(r
);
6337 r
= sd_bus_message_append(m
, "b", arg_runtime
);
6339 return bus_log_create_error(r
);
6343 r
= sd_bus_message_append(m
, "b", arg_force
);
6345 return bus_log_create_error(r
);
6348 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6350 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
6352 if (expect_carries_install_info
) {
6353 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
6355 return bus_log_parse_error(r
);
6358 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6362 /* Try to reload if enabled */
6364 r
= daemon_reload(argc
, argv
, userdata
);
6369 if (carries_install_info
== 0 && !ignore_carries_install_info
)
6370 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6371 "settings in the [Install] section, and DefaultInstance for template units).\n"
6372 "This means they are not meant to be enabled using systemctl.\n"
6373 "Possible reasons for having this kind of units are:\n"
6374 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6375 " .wants/ or .requires/ directory.\n"
6376 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6377 " a requirement dependency on it.\n"
6378 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6379 " D-Bus, udev, scripted systemctl call, ...).\n"
6380 "4) In case of template units, the unit is meant to be enabled with some\n"
6381 " instance name specified.");
6383 if (arg_now
&& STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
6387 r
= acquire_bus(BUS_MANAGER
, &bus
);
6391 len
= strv_length(names
);
6393 char *new_args
[len
+ 2];
6395 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
6396 for (i
= 0; i
< len
; i
++)
6397 new_args
[i
+ 1] = basename(names
[i
]);
6398 new_args
[i
+ 1] = NULL
;
6400 r
= start_unit(len
+ 1, new_args
, userdata
);
6405 unit_file_changes_free(changes
, n_changes
);
6410 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
6411 _cleanup_strv_free_
char **names
= NULL
;
6412 _cleanup_free_
char *target
= NULL
;
6413 const char *verb
= argv
[0];
6414 UnitFileChange
*changes
= NULL
;
6415 unsigned n_changes
= 0;
6422 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
6424 return log_error_errno(r
, "Failed to mangle unit name: %m");
6426 r
= mangle_names(strv_skip(argv
, 2), &names
);
6430 if (streq(verb
, "add-wants"))
6432 else if (streq(verb
, "add-requires"))
6433 dep
= UNIT_REQUIRES
;
6435 assert_not_reached("Unknown verb");
6437 if (install_client_side()) {
6438 r
= unit_file_add_dependency(arg_scope
, args_to_flags(), arg_root
, names
, target
, dep
, &changes
, &n_changes
);
6439 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
6444 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6445 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6448 r
= acquire_bus(BUS_MANAGER
, &bus
);
6452 polkit_agent_open_maybe();
6454 r
= sd_bus_message_new_method_call(
6457 "org.freedesktop.systemd1",
6458 "/org/freedesktop/systemd1",
6459 "org.freedesktop.systemd1.Manager",
6460 "AddDependencyUnitFiles");
6462 return bus_log_create_error(r
);
6464 r
= sd_bus_message_append_strv(m
, names
);
6466 return bus_log_create_error(r
);
6468 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
6470 return bus_log_create_error(r
);
6472 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6474 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
6476 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6480 if (arg_no_reload
) {
6485 r
= daemon_reload(argc
, argv
, userdata
);
6489 unit_file_changes_free(changes
, n_changes
);
6494 static int preset_all(int argc
, char *argv
[], void *userdata
) {
6495 UnitFileChange
*changes
= NULL
;
6496 unsigned n_changes
= 0;
6499 if (install_client_side()) {
6500 r
= unit_file_preset_all(arg_scope
, args_to_flags(), arg_root
, arg_preset_mode
, &changes
, &n_changes
);
6501 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
6506 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6507 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6510 r
= acquire_bus(BUS_MANAGER
, &bus
);
6514 polkit_agent_open_maybe();
6516 r
= sd_bus_call_method(
6518 "org.freedesktop.systemd1",
6519 "/org/freedesktop/systemd1",
6520 "org.freedesktop.systemd1.Manager",
6521 "PresetAllUnitFiles",
6525 unit_file_preset_mode_to_string(arg_preset_mode
),
6529 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
6531 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6535 if (arg_no_reload
) {
6540 r
= daemon_reload(argc
, argv
, userdata
);
6544 unit_file_changes_free(changes
, n_changes
);
6549 static int show_installation_targets_client_side(const char *name
) {
6550 UnitFileChange
*changes
= NULL
;
6551 unsigned n_changes
= 0, i
;
6552 UnitFileFlags flags
;
6556 p
= STRV_MAKE(name
);
6557 flags
= UNIT_FILE_DRY_RUN
|
6558 (arg_runtime
? UNIT_FILE_RUNTIME
: 0);
6560 r
= unit_file_disable(UNIT_FILE_SYSTEM
, flags
, NULL
, p
, &changes
, &n_changes
);
6562 return log_error_errno(r
, "Failed to get file links for %s: %m", name
);
6564 for (i
= 0; i
< n_changes
; i
++)
6565 if (changes
[i
].type
== UNIT_FILE_UNLINK
)
6566 printf(" %s\n", changes
[i
].path
);
6571 static int show_installation_targets(sd_bus
*bus
, const char *name
) {
6572 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6573 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6577 r
= sd_bus_call_method(
6579 "org.freedesktop.systemd1",
6580 "/org/freedesktop/systemd1",
6581 "org.freedesktop.systemd1.Manager",
6585 "sb", name
, arg_runtime
);
6587 return log_error_errno(r
, "Failed to get unit file links for %s: %s", name
, bus_error_message(&error
, r
));
6589 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
6591 return bus_log_parse_error(r
);
6593 while ((r
= sd_bus_message_read(reply
, "s", &link
)) > 0)
6594 printf(" %s\n", link
);
6597 return bus_log_parse_error(r
);
6599 r
= sd_bus_message_exit_container(reply
);
6601 return bus_log_parse_error(r
);
6606 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
6608 _cleanup_strv_free_
char **names
= NULL
;
6613 r
= mangle_names(strv_skip(argv
, 1), &names
);
6617 r
= enable_sysv_units(argv
[0], names
);
6623 if (install_client_side()) {
6624 STRV_FOREACH(name
, names
) {
6625 UnitFileState state
;
6627 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
6629 return log_error_errno(r
, "Failed to get unit file state for %s: %m", *name
);
6633 UNIT_FILE_ENABLED_RUNTIME
,
6636 UNIT_FILE_GENERATED
))
6640 puts(unit_file_state_to_string(state
));
6642 r
= show_installation_targets_client_side(*name
);
6651 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6654 r
= acquire_bus(BUS_MANAGER
, &bus
);
6658 STRV_FOREACH(name
, names
) {
6659 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6662 r
= sd_bus_call_method(
6664 "org.freedesktop.systemd1",
6665 "/org/freedesktop/systemd1",
6666 "org.freedesktop.systemd1.Manager",
6672 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
6674 r
= sd_bus_message_read(reply
, "s", &s
);
6676 return bus_log_parse_error(r
);
6678 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6684 r
= show_installation_targets(bus
, *name
);
6692 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
6695 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
6696 _cleanup_free_
char *state
= NULL
;
6700 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
6703 return EXIT_FAILURE
;
6706 r
= acquire_bus(BUS_MANAGER
, &bus
);
6710 r
= sd_bus_get_property_string(
6712 "org.freedesktop.systemd1",
6713 "/org/freedesktop/systemd1",
6714 "org.freedesktop.systemd1.Manager",
6727 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
6730 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
6731 _cleanup_free_
char *t
= NULL
;
6735 assert(original_path
);
6738 r
= tempfn_random(new_path
, NULL
, &t
);
6740 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
6742 r
= mkdir_parents(new_path
, 0755);
6744 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
6746 r
= copy_file(original_path
, t
, 0, 0644, 0, COPY_REFLINK
);
6751 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
6754 return log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", new_path
);
6762 static int get_file_to_edit(
6763 const LookupPaths
*paths
,
6767 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
6772 path
= strjoin(paths
->persistent_config
, "/", name
);
6777 run
= strjoin(paths
->runtime_config
, "/", name
);
6783 if (access(path
, F_OK
) >= 0) {
6784 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
6798 static int unit_file_create_new(
6799 const LookupPaths
*paths
,
6800 const char *unit_name
,
6802 char **ret_new_path
,
6803 char **ret_tmp_path
) {
6805 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6809 assert(ret_new_path
);
6810 assert(ret_tmp_path
);
6812 ending
= strjoina(unit_name
, suffix
);
6813 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
6817 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6823 *ret_new_path
= tmp_new_path
;
6824 *ret_tmp_path
= tmp_tmp_path
;
6829 static int unit_file_create_copy(
6830 const LookupPaths
*paths
,
6831 const char *unit_name
,
6832 const char *fragment_path
,
6833 char **ret_new_path
,
6834 char **ret_tmp_path
) {
6836 char *tmp_new_path
, *tmp_tmp_path
;
6839 assert(fragment_path
);
6841 assert(ret_new_path
);
6842 assert(ret_tmp_path
);
6844 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6848 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6851 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6856 if (response
!= 'y') {
6857 log_warning("%s ignored", unit_name
);
6859 return -EKEYREJECTED
;
6863 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6869 *ret_new_path
= tmp_new_path
;
6870 *ret_tmp_path
= tmp_tmp_path
;
6875 static int run_editor(char **paths
) {
6883 return log_error_errno(errno
, "Failed to fork: %m");
6887 char *editor
, **editor_args
= NULL
;
6888 char **tmp_path
, **original_path
, *p
;
6889 unsigned n_editor_args
= 0, i
= 1;
6892 (void) reset_all_signal_handlers();
6893 (void) reset_signal_mask();
6895 argc
= strv_length(paths
)/2 + 1;
6897 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6898 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6899 * we try to execute well known editors
6901 editor
= getenv("SYSTEMD_EDITOR");
6903 editor
= getenv("EDITOR");
6905 editor
= getenv("VISUAL");
6907 if (!isempty(editor
)) {
6908 editor_args
= strv_split(editor
, WHITESPACE
);
6911 _exit(EXIT_FAILURE
);
6913 n_editor_args
= strv_length(editor_args
);
6914 argc
+= n_editor_args
- 1;
6916 args
= newa(const char*, argc
+ 1);
6918 if (n_editor_args
> 0) {
6919 args
[0] = editor_args
[0];
6920 for (; i
< n_editor_args
; i
++)
6921 args
[i
] = editor_args
[i
];
6924 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6925 args
[i
] = *tmp_path
;
6930 if (n_editor_args
> 0)
6931 execvp(args
[0], (char* const*) args
);
6933 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6935 execvp(p
, (char* const*) args
);
6936 /* We do not fail if the editor doesn't exist
6937 * because we want to try each one of them before
6940 if (errno
!= ENOENT
) {
6941 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6942 _exit(EXIT_FAILURE
);
6946 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6947 _exit(EXIT_FAILURE
);
6950 r
= wait_for_terminate_and_warn("editor", pid
, true);
6952 return log_error_errno(r
, "Failed to wait for child: %m");
6957 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6958 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6965 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6969 STRV_FOREACH(name
, names
) {
6970 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
, *tmp_name
= NULL
;
6971 const char *unit_name
;
6973 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6981 log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
6982 arg_scope
== UNIT_FILE_GLOBAL
? " --global" :
6983 arg_scope
== UNIT_FILE_USER
? " --user" : "",
6988 /* Create a new unit from scratch */
6990 r
= unit_file_create_new(&lp
, unit_name
,
6991 arg_full
? NULL
: ".d/override.conf",
6992 &new_path
, &tmp_path
);
6996 unit_name
= basename(path
);
6997 /* We follow unit aliases, but we need to propagate the instance */
6998 if (unit_name_is_valid(*name
, UNIT_NAME_INSTANCE
) &&
6999 unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
7000 _cleanup_free_
char *instance
= NULL
;
7002 r
= unit_name_to_instance(*name
, &instance
);
7006 r
= unit_name_replace_instance(unit_name
, instance
, &tmp_name
);
7010 unit_name
= tmp_name
;
7014 r
= unit_file_create_copy(&lp
, unit_name
, path
, &new_path
, &tmp_path
);
7016 r
= unit_file_create_new(&lp
, unit_name
, ".d/override.conf", &new_path
, &tmp_path
);
7021 r
= strv_push_pair(paths
, new_path
, tmp_path
);
7024 new_path
= tmp_path
= NULL
;
7030 static int edit(int argc
, char *argv
[], void *userdata
) {
7031 _cleanup_strv_free_
char **names
= NULL
;
7032 _cleanup_strv_free_
char **paths
= NULL
;
7033 char **original
, **tmp
;
7038 log_error("Cannot edit units if not on a tty.");
7042 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
7043 log_error("Cannot edit units remotely.");
7047 r
= acquire_bus(BUS_MANAGER
, &bus
);
7051 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
7053 return log_error_errno(r
, "Failed to expand names: %m");
7055 r
= find_paths_to_edit(bus
, names
, &paths
);
7059 if (strv_isempty(paths
))
7062 r
= run_editor(paths
);
7066 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
7067 /* If the temporary file is empty we ignore it. It's
7068 * useful if the user wants to cancel its modification
7070 if (null_or_empty_path(*tmp
)) {
7071 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
7075 r
= rename(*tmp
, *original
);
7077 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
7084 if (!arg_no_reload
&& !install_client_side())
7085 r
= daemon_reload(argc
, argv
, userdata
);
7088 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
7089 (void) unlink(*tmp
);
7091 /* Removing empty dropin dirs */
7093 _cleanup_free_
char *dir
;
7095 dir
= dirname_malloc(*original
);
7099 /* no need to check if the dir is empty, rmdir
7100 * does nothing if it is not the case.
7109 static void systemctl_help(void) {
7111 pager_open(arg_no_pager
, false);
7113 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
7114 "Query or send control commands to the systemd manager.\n\n"
7115 " -h --help Show this help\n"
7116 " --version Show package version\n"
7117 " --system Connect to system manager\n"
7118 " --user Connect to user service manager\n"
7119 " -H --host=[USER@]HOST\n"
7120 " Operate on remote host\n"
7121 " -M --machine=CONTAINER\n"
7122 " Operate on local container\n"
7123 " -t --type=TYPE List units of a particular type\n"
7124 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
7125 " -p --property=NAME Show only properties by this name\n"
7126 " -a --all Show all properties/all units currently in memory,\n"
7127 " including dead/empty ones. To list all units installed on\n"
7128 " the system, use the 'list-unit-files' command instead.\n"
7129 " --failed Same as --state=failed\n"
7130 " -l --full Don't ellipsize unit names on output\n"
7131 " -r --recursive Show unit list of host and local containers\n"
7132 " --reverse Show reverse dependencies with 'list-dependencies'\n"
7133 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
7134 " queueing a new job\n"
7135 " --show-types When showing sockets, explicitly show their type\n"
7136 " --value When showing properties, only print the value\n"
7137 " -i --ignore-inhibitors\n"
7138 " When shutting down or sleeping, ignore inhibitors\n"
7139 " --kill-who=WHO Who to send signal to\n"
7140 " -s --signal=SIGNAL Which signal to send\n"
7141 " --now Start or stop unit in addition to enabling or disabling it\n"
7142 " -q --quiet Suppress output\n"
7143 " --wait For (re)start, wait until service stopped again\n"
7144 " --no-block Do not wait until operation finished\n"
7145 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7146 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
7147 " --no-legend Do not print a legend (column headers and hints)\n"
7148 " --no-pager Do not pipe output into a pager\n"
7149 " --no-ask-password\n"
7150 " Do not ask for system passwords\n"
7151 " --global Enable/disable/mask unit files globally\n"
7152 " --runtime Enable/disable/mask unit files temporarily until next\n"
7154 " -f --force When enabling unit files, override existing symlinks\n"
7155 " When shutting down, execute action immediately\n"
7156 " --preset-mode= Apply only enable, only disable, or all presets\n"
7157 " --root=PATH Enable/disable/mask unit files in the specified root\n"
7159 " -n --lines=INTEGER Number of journal entries to show\n"
7160 " -o --output=STRING Change journal output mode (short, short-precise,\n"
7161 " short-iso, short-iso-precise, short-full,\n"
7162 " short-monotonic, short-unix,\n"
7163 " verbose, export, json, json-pretty, json-sse, cat)\n"
7164 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
7165 " --plain Print unit dependencies as a list instead of a tree\n\n"
7167 " list-units [PATTERN...] List units currently in memory\n"
7168 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
7170 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
7172 " start NAME... Start (activate) one or more units\n"
7173 " stop NAME... Stop (deactivate) one or more units\n"
7174 " reload NAME... Reload one or more units\n"
7175 " restart NAME... Start or restart one or more units\n"
7176 " try-restart NAME... Restart one or more units if active\n"
7177 " reload-or-restart NAME... Reload one or more units if possible,\n"
7178 " otherwise start or restart\n"
7179 " try-reload-or-restart NAME... If active, reload one or more units,\n"
7180 " if supported, otherwise restart\n"
7181 " isolate NAME Start one unit and stop all others\n"
7182 " kill NAME... Send signal to processes of a unit\n"
7183 " is-active PATTERN... Check whether units are active\n"
7184 " is-failed PATTERN... Check whether units are failed\n"
7185 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
7186 " show [PATTERN...|JOB...] Show properties of one or more\n"
7187 " units/jobs or the manager\n"
7188 " cat PATTERN... Show files and drop-ins of one or more units\n"
7189 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
7190 " help PATTERN...|PID... Show manual for one or more units\n"
7191 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
7193 " list-dependencies [NAME] Recursively show units which are required\n"
7194 " or wanted by this unit or by which this\n"
7195 " unit is required or wanted\n\n"
7196 "Unit File Commands:\n"
7197 " list-unit-files [PATTERN...] List installed unit files\n"
7198 " enable [NAME...|PATH...] Enable one or more unit files\n"
7199 " disable NAME... Disable one or more unit files\n"
7200 " reenable NAME... Reenable one or more unit files\n"
7201 " preset NAME... Enable/disable one or more unit files\n"
7202 " based on preset configuration\n"
7203 " preset-all Enable/disable all unit files based on\n"
7204 " preset configuration\n"
7205 " is-enabled NAME... Check whether unit files are enabled\n"
7206 " mask NAME... Mask one or more units\n"
7207 " unmask NAME... Unmask one or more units\n"
7208 " link PATH... Link one or more units files into\n"
7209 " the search path\n"
7210 " revert NAME... Revert one or more unit files to vendor\n"
7212 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
7213 " on specified one or more units\n"
7214 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
7215 " on specified one or more units\n"
7216 " edit NAME... Edit one or more unit files\n"
7217 " get-default Get the name of the default target\n"
7218 " set-default NAME Set the default target\n\n"
7219 "Machine Commands:\n"
7220 " list-machines [PATTERN...] List local containers and host\n\n"
7222 " list-jobs [PATTERN...] List jobs\n"
7223 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
7224 "Environment Commands:\n"
7225 " show-environment Dump environment\n"
7226 " set-environment NAME=VALUE... Set one or more environment variables\n"
7227 " unset-environment NAME... Unset one or more environment variables\n"
7228 " import-environment [NAME...] Import all or some environment variables\n\n"
7229 "Manager Lifecycle Commands:\n"
7230 " daemon-reload Reload systemd manager configuration\n"
7231 " daemon-reexec Reexecute systemd manager\n\n"
7232 "System Commands:\n"
7233 " is-system-running Check whether system is fully running\n"
7234 " default Enter system default mode\n"
7235 " rescue Enter system rescue mode\n"
7236 " emergency Enter system emergency mode\n"
7237 " halt Shut down and halt the system\n"
7238 " poweroff Shut down and power-off the system\n"
7239 " reboot [ARG] Shut down and reboot the system\n"
7240 " kexec Shut down and reboot the system with kexec\n"
7241 " exit [EXIT_CODE] Request user instance or container exit\n"
7242 " switch-root ROOT [INIT] Change to a different root file system\n"
7243 " suspend Suspend the system\n"
7244 " hibernate Hibernate the system\n"
7245 " hybrid-sleep Hibernate and suspend the system\n",
7246 program_invocation_short_name
);
7249 static void halt_help(void) {
7250 printf("%s [OPTIONS...]%s\n\n"
7251 "%s the system.\n\n"
7252 " --help Show this help\n"
7253 " --halt Halt the machine\n"
7254 " -p --poweroff Switch off the machine\n"
7255 " --reboot Reboot the machine\n"
7256 " -f --force Force immediate halt/power-off/reboot\n"
7257 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
7258 " -d --no-wtmp Don't write wtmp record\n"
7259 " --no-wall Don't send wall message before halt/power-off/reboot\n",
7260 program_invocation_short_name
,
7261 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
7262 arg_action
== ACTION_REBOOT
? "Reboot" :
7263 arg_action
== ACTION_POWEROFF
? "Power off" :
7267 static void shutdown_help(void) {
7268 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
7269 "Shut down the system.\n\n"
7270 " --help Show this help\n"
7271 " -H --halt Halt the machine\n"
7272 " -P --poweroff Power-off the machine\n"
7273 " -r --reboot Reboot the machine\n"
7274 " -h Equivalent to --poweroff, overridden by --halt\n"
7275 " -k Don't halt/power-off/reboot, just send warnings\n"
7276 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7277 " -c Cancel a pending shutdown\n",
7278 program_invocation_short_name
);
7281 static void telinit_help(void) {
7282 printf("%s [OPTIONS...] {COMMAND}\n\n"
7283 "Send control commands to the init daemon.\n\n"
7284 " --help Show this help\n"
7285 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7287 " 0 Power-off the machine\n"
7288 " 6 Reboot the machine\n"
7289 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7290 " 1, s, S Enter rescue mode\n"
7291 " q, Q Reload init daemon configuration\n"
7292 " u, U Reexecute init daemon\n",
7293 program_invocation_short_name
);
7296 static void runlevel_help(void) {
7297 printf("%s [OPTIONS...]\n\n"
7298 "Prints the previous and current runlevel of the init system.\n\n"
7299 " --help Show this help\n",
7300 program_invocation_short_name
);
7303 static void help_types(void) {
7307 puts("Available unit types:");
7308 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
7309 puts(unit_type_to_string(i
));
7312 static void help_states(void) {
7316 puts("Available unit load states:");
7317 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
7318 puts(unit_load_state_to_string(i
));
7321 puts("\nAvailable unit active states:");
7322 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
7323 puts(unit_active_state_to_string(i
));
7326 puts("\nAvailable automount unit substates:");
7327 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
7328 puts(automount_state_to_string(i
));
7331 puts("\nAvailable device unit substates:");
7332 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
7333 puts(device_state_to_string(i
));
7336 puts("\nAvailable mount unit substates:");
7337 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
7338 puts(mount_state_to_string(i
));
7341 puts("\nAvailable path unit substates:");
7342 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
7343 puts(path_state_to_string(i
));
7346 puts("\nAvailable scope unit substates:");
7347 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
7348 puts(scope_state_to_string(i
));
7351 puts("\nAvailable service unit substates:");
7352 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
7353 puts(service_state_to_string(i
));
7356 puts("\nAvailable slice unit substates:");
7357 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
7358 puts(slice_state_to_string(i
));
7361 puts("\nAvailable socket unit substates:");
7362 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
7363 puts(socket_state_to_string(i
));
7366 puts("\nAvailable swap unit substates:");
7367 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
7368 puts(swap_state_to_string(i
));
7371 puts("\nAvailable target unit substates:");
7372 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
7373 puts(target_state_to_string(i
));
7376 puts("\nAvailable timer unit substates:");
7377 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
7378 puts(timer_state_to_string(i
));
7381 static int systemctl_parse_argv(int argc
, char *argv
[]) {
7390 ARG_IGNORE_DEPENDENCIES
,
7403 ARG_NO_ASK_PASSWORD
,
7417 static const struct option options
[] = {
7418 { "help", no_argument
, NULL
, 'h' },
7419 { "version", no_argument
, NULL
, ARG_VERSION
},
7420 { "type", required_argument
, NULL
, 't' },
7421 { "property", required_argument
, NULL
, 'p' },
7422 { "all", no_argument
, NULL
, 'a' },
7423 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
7424 { "after", no_argument
, NULL
, ARG_AFTER
},
7425 { "before", no_argument
, NULL
, ARG_BEFORE
},
7426 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
7427 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
7428 { "full", no_argument
, NULL
, 'l' },
7429 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
7430 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
7431 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
7432 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
7433 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
7434 { "value", no_argument
, NULL
, ARG_VALUE
},
7435 { "user", no_argument
, NULL
, ARG_USER
},
7436 { "system", no_argument
, NULL
, ARG_SYSTEM
},
7437 { "global", no_argument
, NULL
, ARG_GLOBAL
},
7438 { "wait", no_argument
, NULL
, ARG_WAIT
},
7439 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
7440 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
7441 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
7442 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7443 { "quiet", no_argument
, NULL
, 'q' },
7444 { "root", required_argument
, NULL
, ARG_ROOT
},
7445 { "force", no_argument
, NULL
, ARG_FORCE
},
7446 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
7447 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
7448 { "signal", required_argument
, NULL
, 's' },
7449 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
7450 { "host", required_argument
, NULL
, 'H' },
7451 { "machine", required_argument
, NULL
, 'M' },
7452 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
7453 { "lines", required_argument
, NULL
, 'n' },
7454 { "output", required_argument
, NULL
, 'o' },
7455 { "plain", no_argument
, NULL
, ARG_PLAIN
},
7456 { "state", required_argument
, NULL
, ARG_STATE
},
7457 { "recursive", no_argument
, NULL
, 'r' },
7458 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
7459 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
7460 { "now", no_argument
, NULL
, ARG_NOW
},
7461 { "message", required_argument
, NULL
, ARG_MESSAGE
},
7471 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7472 arg_ask_password
= true;
7474 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
7486 if (isempty(optarg
)) {
7487 log_error("--type= requires arguments.");
7491 for (p
= optarg
;;) {
7492 _cleanup_free_
char *type
= NULL
;
7494 r
= extract_first_word(&p
, &type
, ",", 0);
7496 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
7500 if (streq(type
, "help")) {
7505 if (unit_type_from_string(type
) >= 0) {
7506 if (strv_push(&arg_types
, type
) < 0)
7512 /* It's much nicer to use --state= for
7513 * load states, but let's support this
7514 * in --types= too for compatibility
7515 * with old versions */
7516 if (unit_load_state_from_string(type
) >= 0) {
7517 if (strv_push(&arg_states
, type
) < 0)
7523 log_error("Unknown unit type or load state '%s'.", type
);
7524 log_info("Use -t help to see a list of allowed values.");
7532 /* Make sure that if the empty property list
7533 was specified, we won't show any properties. */
7534 if (isempty(optarg
) && !arg_properties
) {
7535 arg_properties
= new0(char*, 1);
7536 if (!arg_properties
)
7539 for (p
= optarg
;;) {
7540 _cleanup_free_
char *prop
= NULL
;
7542 r
= extract_first_word(&p
, &prop
, ",", 0);
7544 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
7548 if (strv_push(&arg_properties
, prop
) < 0)
7554 /* If the user asked for a particular
7555 * property, show it to him, even if it is
7567 arg_dependency
= DEPENDENCY_REVERSE
;
7571 arg_dependency
= DEPENDENCY_AFTER
;
7572 arg_jobs_after
= true;
7576 arg_dependency
= DEPENDENCY_BEFORE
;
7577 arg_jobs_before
= true;
7580 case ARG_SHOW_TYPES
:
7581 arg_show_types
= true;
7589 arg_job_mode
= optarg
;
7593 arg_job_mode
= "fail";
7596 case ARG_IRREVERSIBLE
:
7597 arg_job_mode
= "replace-irreversibly";
7600 case ARG_IGNORE_DEPENDENCIES
:
7601 arg_job_mode
= "ignore-dependencies";
7605 arg_scope
= UNIT_FILE_USER
;
7609 arg_scope
= UNIT_FILE_SYSTEM
;
7613 arg_scope
= UNIT_FILE_GLOBAL
;
7621 arg_no_block
= true;
7625 arg_no_legend
= true;
7629 arg_no_pager
= true;
7637 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
7647 if (strv_extend(&arg_states
, "failed") < 0)
7665 arg_no_reload
= true;
7669 arg_kill_who
= optarg
;
7673 arg_signal
= signal_from_string_try_harder(optarg
);
7674 if (arg_signal
< 0) {
7675 log_error("Failed to parse signal string %s.", optarg
);
7680 case ARG_NO_ASK_PASSWORD
:
7681 arg_ask_password
= false;
7685 arg_transport
= BUS_TRANSPORT_REMOTE
;
7690 arg_transport
= BUS_TRANSPORT_MACHINE
;
7699 if (safe_atou(optarg
, &arg_lines
) < 0) {
7700 log_error("Failed to parse lines '%s'", optarg
);
7706 arg_output
= output_mode_from_string(optarg
);
7707 if (arg_output
< 0) {
7708 log_error("Unknown output '%s'.", optarg
);
7714 arg_ignore_inhibitors
= true;
7721 case ARG_FIRMWARE_SETUP
:
7722 arg_firmware_setup
= true;
7726 if (isempty(optarg
)) {
7727 log_error("--state= requires arguments.");
7731 for (p
= optarg
;;) {
7732 _cleanup_free_
char *s
= NULL
;
7734 r
= extract_first_word(&p
, &s
, ",", 0);
7736 return log_error_errno(r
, "Failed to parse state: %s", optarg
);
7740 if (streq(s
, "help")) {
7745 if (strv_push(&arg_states
, s
) < 0)
7754 if (geteuid() != 0) {
7755 log_error("--recursive requires root privileges.");
7759 arg_recursive
= true;
7762 case ARG_PRESET_MODE
:
7764 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
7765 if (arg_preset_mode
< 0) {
7766 log_error("Failed to parse preset mode: %s.", optarg
);
7777 if (strv_extend(&arg_wall
, optarg
) < 0)
7785 assert_not_reached("Unhandled option");
7788 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
7789 log_error("Cannot access user instance remotely.");
7793 if (arg_wait
&& arg_no_block
) {
7794 log_error("--wait may not be combined with --no-block.");
7801 static int halt_parse_argv(int argc
, char *argv
[]) {
7810 static const struct option options
[] = {
7811 { "help", no_argument
, NULL
, ARG_HELP
},
7812 { "halt", no_argument
, NULL
, ARG_HALT
},
7813 { "poweroff", no_argument
, NULL
, 'p' },
7814 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
7815 { "force", no_argument
, NULL
, 'f' },
7816 { "wtmp-only", no_argument
, NULL
, 'w' },
7817 { "no-wtmp", no_argument
, NULL
, 'd' },
7818 { "no-sync", no_argument
, NULL
, 'n' },
7819 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7828 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
7829 if (IN_SET(runlevel
, '0', '6'))
7832 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
7840 arg_action
= ACTION_HALT
;
7844 if (arg_action
!= ACTION_REBOOT
)
7845 arg_action
= ACTION_POWEROFF
;
7849 arg_action
= ACTION_REBOOT
;
7874 /* Compatibility nops */
7881 assert_not_reached("Unhandled option");
7884 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7885 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7888 } else if (optind
< argc
) {
7889 log_error("Too many arguments.");
7896 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7900 if (streq(t
, "now"))
7902 else if (!strchr(t
, ':')) {
7905 if (safe_atou64(t
, &u
) < 0)
7908 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7917 hour
= strtol(t
, &e
, 10);
7918 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7921 minute
= strtol(e
+1, &e
, 10);
7922 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7925 n
= now(CLOCK_REALTIME
);
7926 s
= (time_t) (n
/ USEC_PER_SEC
);
7928 assert_se(localtime_r(&s
, &tm
));
7930 tm
.tm_hour
= (int) hour
;
7931 tm
.tm_min
= (int) minute
;
7934 assert_se(s
= mktime(&tm
));
7936 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7939 *_u
+= USEC_PER_DAY
;
7945 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7952 static const struct option options
[] = {
7953 { "help", no_argument
, NULL
, ARG_HELP
},
7954 { "halt", no_argument
, NULL
, 'H' },
7955 { "poweroff", no_argument
, NULL
, 'P' },
7956 { "reboot", no_argument
, NULL
, 'r' },
7957 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7958 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7968 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7976 arg_action
= ACTION_HALT
;
7980 arg_action
= ACTION_POWEROFF
;
7985 arg_action
= ACTION_KEXEC
;
7987 arg_action
= ACTION_REBOOT
;
7991 arg_action
= ACTION_KEXEC
;
7995 if (arg_action
!= ACTION_HALT
)
7996 arg_action
= ACTION_POWEROFF
;
8011 /* Compatibility nops */
8015 arg_action
= ACTION_CANCEL_SHUTDOWN
;
8022 assert_not_reached("Unhandled option");
8025 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
8026 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
8028 log_error("Failed to parse time specification: %s", argv
[optind
]);
8032 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
8034 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
8035 /* No time argument for shutdown cancel */
8036 wall
= argv
+ optind
;
8037 else if (argc
> optind
+ 1)
8038 /* We skip the time argument */
8039 wall
= argv
+ optind
+ 1;
8042 arg_wall
= strv_copy(wall
);
8052 static int telinit_parse_argv(int argc
, char *argv
[]) {
8059 static const struct option options
[] = {
8060 { "help", no_argument
, NULL
, ARG_HELP
},
8061 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
8065 static const struct {
8069 { '0', ACTION_POWEROFF
},
8070 { '6', ACTION_REBOOT
},
8071 { '1', ACTION_RESCUE
},
8072 { '2', ACTION_RUNLEVEL2
},
8073 { '3', ACTION_RUNLEVEL3
},
8074 { '4', ACTION_RUNLEVEL4
},
8075 { '5', ACTION_RUNLEVEL5
},
8076 { 's', ACTION_RESCUE
},
8077 { 'S', ACTION_RESCUE
},
8078 { 'q', ACTION_RELOAD
},
8079 { 'Q', ACTION_RELOAD
},
8080 { 'u', ACTION_REEXEC
},
8081 { 'U', ACTION_REEXEC
}
8090 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
8105 assert_not_reached("Unhandled option");
8108 if (optind
>= argc
) {
8109 log_error("%s: required argument missing.", program_invocation_short_name
);
8113 if (optind
+ 1 < argc
) {
8114 log_error("Too many arguments.");
8118 if (strlen(argv
[optind
]) != 1) {
8119 log_error("Expected single character argument.");
8123 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
8124 if (table
[i
].from
== argv
[optind
][0])
8127 if (i
>= ELEMENTSOF(table
)) {
8128 log_error("Unknown command '%s'.", argv
[optind
]);
8132 arg_action
= table
[i
].to
;
8139 static int runlevel_parse_argv(int argc
, char *argv
[]) {
8145 static const struct option options
[] = {
8146 { "help", no_argument
, NULL
, ARG_HELP
},
8155 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
8166 assert_not_reached("Unhandled option");
8169 if (optind
< argc
) {
8170 log_error("Too many arguments.");
8177 static int parse_argv(int argc
, char *argv
[]) {
8181 if (program_invocation_short_name
) {
8183 if (strstr(program_invocation_short_name
, "halt")) {
8184 arg_action
= ACTION_HALT
;
8185 return halt_parse_argv(argc
, argv
);
8186 } else if (strstr(program_invocation_short_name
, "poweroff")) {
8187 arg_action
= ACTION_POWEROFF
;
8188 return halt_parse_argv(argc
, argv
);
8189 } else if (strstr(program_invocation_short_name
, "reboot")) {
8191 arg_action
= ACTION_KEXEC
;
8193 arg_action
= ACTION_REBOOT
;
8194 return halt_parse_argv(argc
, argv
);
8195 } else if (strstr(program_invocation_short_name
, "shutdown")) {
8196 arg_action
= ACTION_POWEROFF
;
8197 return shutdown_parse_argv(argc
, argv
);
8198 } else if (strstr(program_invocation_short_name
, "init")) {
8200 if (sd_booted() > 0) {
8201 arg_action
= _ACTION_INVALID
;
8202 return telinit_parse_argv(argc
, argv
);
8204 /* Hmm, so some other init system is
8205 * running, we need to forward this
8206 * request to it. For now we simply
8207 * guess that it is Upstart. */
8209 execv(TELINIT
, argv
);
8211 log_error("Couldn't find an alternative telinit implementation to spawn.");
8215 } else if (strstr(program_invocation_short_name
, "runlevel")) {
8216 arg_action
= ACTION_RUNLEVEL
;
8217 return runlevel_parse_argv(argc
, argv
);
8221 arg_action
= ACTION_SYSTEMCTL
;
8222 return systemctl_parse_argv(argc
, argv
);
8225 #if HAVE_SYSV_COMPAT
8226 _pure_
static int action_to_runlevel(void) {
8228 static const char table
[_ACTION_MAX
] = {
8229 [ACTION_HALT
] = '0',
8230 [ACTION_POWEROFF
] = '0',
8231 [ACTION_REBOOT
] = '6',
8232 [ACTION_RUNLEVEL2
] = '2',
8233 [ACTION_RUNLEVEL3
] = '3',
8234 [ACTION_RUNLEVEL4
] = '4',
8235 [ACTION_RUNLEVEL5
] = '5',
8236 [ACTION_RESCUE
] = '1'
8239 assert(arg_action
>= 0 && arg_action
< _ACTION_MAX
);
8241 return table
[arg_action
];
8245 static int talk_initctl(void) {
8246 #if HAVE_SYSV_COMPAT
8247 struct init_request request
= {
8248 .magic
= INIT_MAGIC
,
8250 .cmd
= INIT_CMD_RUNLVL
8253 _cleanup_close_
int fd
= -1;
8257 rl
= action_to_runlevel();
8261 request
.runlevel
= rl
;
8263 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
8265 if (errno
== ENOENT
)
8268 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
8271 r
= loop_write(fd
, &request
, sizeof(request
), false);
8273 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
8281 static int systemctl_main(int argc
, char *argv
[]) {
8283 static const Verb verbs
[] = {
8284 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
8285 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
8286 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
8287 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
8288 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
8289 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
8290 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, trivial_method
},
8291 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
8292 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8293 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8294 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8295 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8296 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8297 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8298 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8299 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
8300 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8301 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
8302 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8303 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
8304 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
8305 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
8306 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8307 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8308 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
8309 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8310 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
8311 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8312 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8313 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8314 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8315 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
8316 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8317 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8318 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
8319 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8320 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8321 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_system_special
},
8322 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8323 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8324 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8325 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8326 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
8327 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8328 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8329 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
8330 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
8331 { "enable", 2, VERB_ANY
, 0, enable_unit
},
8332 { "disable", 2, VERB_ANY
, 0, enable_unit
},
8333 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
8334 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
8335 { "preset", 2, VERB_ANY
, 0, enable_unit
},
8336 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
8337 { "mask", 2, VERB_ANY
, 0, enable_unit
},
8338 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
8339 { "link", 2, VERB_ANY
, 0, enable_unit
},
8340 { "revert", 2, VERB_ANY
, 0, enable_unit
},
8341 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
8342 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
8343 { "set-default", 2, 2, 0, set_default
},
8344 { "get-default", VERB_ANY
, 1, 0, get_default
},
8345 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
8346 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
8347 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
8348 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
8349 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
8353 return dispatch_verb(argc
, argv
, verbs
, NULL
);
8356 static int reload_with_fallback(void) {
8358 /* First, try systemd via D-Bus. */
8359 if (daemon_reload(0, NULL
, NULL
) >= 0)
8362 /* Nothing else worked, so let's try signals */
8363 assert(IN_SET(arg_action
, ACTION_RELOAD
, ACTION_REEXEC
));
8365 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
8366 return log_error_errno(errno
, "kill() failed: %m");
8371 static int start_with_fallback(void) {
8373 /* First, try systemd via D-Bus. */
8374 if (start_unit(0, NULL
, NULL
) >= 0)
8377 /* Nothing else worked, so let's try /dev/initctl */
8378 if (talk_initctl() > 0)
8381 log_error("Failed to talk to init daemon.");
8385 static int halt_now(enum action a
) {
8388 /* The kernel will automaticall flush ATA disks and suchlike
8389 * on reboot(), but the file systems need to be synce'd
8390 * explicitly in advance. */
8394 /* Make sure C-A-D is handled by the kernel from this point
8396 (void) reboot(RB_ENABLE_CAD
);
8402 log_info("Halting.");
8403 (void) reboot(RB_HALT_SYSTEM
);
8406 case ACTION_POWEROFF
:
8408 log_info("Powering off.");
8409 (void) reboot(RB_POWER_OFF
);
8413 case ACTION_REBOOT
: {
8414 _cleanup_free_
char *param
= NULL
;
8416 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
8417 if (r
< 0 && r
!= -ENOENT
)
8418 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
8420 if (!isempty(param
)) {
8422 log_info("Rebooting with argument '%s'.", param
);
8423 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
8424 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
8428 log_info("Rebooting.");
8429 (void) reboot(RB_AUTOBOOT
);
8434 assert_not_reached("Unknown action.");
8438 static int logind_schedule_shutdown(void) {
8441 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8442 char date
[FORMAT_TIMESTAMP_MAX
];
8447 r
= acquire_bus(BUS_FULL
, &bus
);
8451 switch (arg_action
) {
8455 case ACTION_POWEROFF
:
8456 action
= "poweroff";
8471 action
= strjoina("dry-", action
);
8473 (void) logind_set_wall_message();
8475 r
= sd_bus_call_method(
8477 "org.freedesktop.login1",
8478 "/org/freedesktop/login1",
8479 "org.freedesktop.login1.Manager",
8487 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
8490 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
8493 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8498 static int halt_main(void) {
8501 r
= logind_check_inhibitors(arg_action
);
8506 return logind_schedule_shutdown();
8508 if (geteuid() != 0) {
8509 if (arg_dry
|| arg_force
> 0) {
8510 log_error("Must be root.");
8514 /* Try logind if we are a normal user and no special
8515 * mode applies. Maybe PolicyKit allows us to shutdown
8517 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
, ACTION_HALT
)) {
8518 r
= logind_reboot(arg_action
);
8521 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
8522 /* requested operation is not
8523 * supported on the local system or
8524 * already in progress */
8526 /* on all other errors, try low-level operation */
8530 if (!arg_dry
&& !arg_force
)
8531 return start_with_fallback();
8533 assert(geteuid() == 0);
8536 if (sd_booted() > 0)
8537 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8539 r
= utmp_put_shutdown();
8541 log_warning_errno(r
, "Failed to write utmp record: %m");
8548 r
= halt_now(arg_action
);
8549 return log_error_errno(r
, "Failed to reboot: %m");
8552 static int runlevel_main(void) {
8553 int r
, runlevel
, previous
;
8555 r
= utmp_get_runlevel(&runlevel
, &previous
);
8562 previous
<= 0 ? 'N' : previous
,
8563 runlevel
<= 0 ? 'N' : runlevel
);
8568 static int logind_cancel_shutdown(void) {
8570 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8574 r
= acquire_bus(BUS_FULL
, &bus
);
8578 (void) logind_set_wall_message();
8580 r
= sd_bus_call_method(
8582 "org.freedesktop.login1",
8583 "/org/freedesktop/login1",
8584 "org.freedesktop.login1.Manager",
8585 "CancelScheduledShutdown",
8589 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
8593 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8598 int main(int argc
, char*argv
[]) {
8601 argv_cmdline
= argv
[0];
8603 setlocale(LC_ALL
, "");
8604 log_parse_environment();
8608 /* Explicitly not on_tty() to avoid setting cached value.
8609 * This becomes relevant for piping output which might be
8611 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
8613 r
= parse_argv(argc
, argv
);
8617 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
8620 log_info("Running in chroot, ignoring request.");
8625 /* systemctl_main() will print an error message for the bus
8626 * connection, but only if it needs to */
8628 switch (arg_action
) {
8630 case ACTION_SYSTEMCTL
:
8631 r
= systemctl_main(argc
, argv
);
8634 /* Legacy command aliases set arg_action. They provide some fallbacks,
8635 * e.g. to tell sysvinit to reboot after you have installed systemd
8639 case ACTION_POWEROFF
:
8645 case ACTION_RUNLEVEL2
:
8646 case ACTION_RUNLEVEL3
:
8647 case ACTION_RUNLEVEL4
:
8648 case ACTION_RUNLEVEL5
:
8650 r
= start_with_fallback();
8655 r
= reload_with_fallback();
8658 case ACTION_CANCEL_SHUTDOWN
:
8659 r
= logind_cancel_shutdown();
8662 case ACTION_RUNLEVEL
:
8663 r
= runlevel_main();
8667 case ACTION_SUSPEND
:
8668 case ACTION_HIBERNATE
:
8669 case ACTION_HYBRID_SLEEP
:
8670 case ACTION_EMERGENCY
:
8671 case ACTION_DEFAULT
:
8672 /* systemctl verbs with no equivalent in the legacy commands.
8673 * These cannot appear in arg_action. Fall through. */
8675 case _ACTION_INVALID
:
8677 assert_not_reached("Unknown action");
8684 ask_password_agent_close();
8685 polkit_agent_close();
8687 strv_free(arg_types
);
8688 strv_free(arg_states
);
8689 strv_free(arg_properties
);
8691 strv_free(arg_wall
);
8694 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8695 return r
< 0 ? EXIT_FAILURE
: r
;