1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
6 Copyright 2013 Marc-Antoine Perennou
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <linux/reboot.h>
31 #include <sys/reboot.h>
32 #include <sys/socket.h>
36 #include "sd-daemon.h"
39 #include "alloc-util.h"
40 #include "bus-common-errors.h"
41 #include "bus-error.h"
42 #include "bus-message.h"
43 #include "bus-unit-util.h"
45 #include "cgroup-show.h"
46 #include "cgroup-util.h"
52 #include "exit-status.h"
55 #include "format-util.h"
57 #include "glob-util.h"
58 #include "hostname-util.h"
63 #include "locale-util.h"
65 #include "logs-show.h"
69 #include "parse-util.h"
70 #include "path-lookup.h"
71 #include "path-util.h"
72 #include "process-util.h"
73 #include "rlimit-util.h"
76 #include "signal-util.h"
77 #include "socket-util.h"
78 #include "spawn-ask-password-agent.h"
79 #include "spawn-polkit-agent.h"
81 #include "stat-util.h"
83 #include "terminal-util.h"
84 #include "unit-name.h"
85 #include "user-util.h"
87 #include "utmp-wtmp.h"
91 /* The init script exit status codes
92 0 program is running or service is OK
93 1 program is dead and /var/run pid file exists
94 2 program is dead and /var/lock lock file exists
95 3 program is not running
96 4 program or service status is unknown
97 5-99 reserved for future LSB use
98 100-149 reserved for distribution use
99 150-199 reserved for application use
103 EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
= 0,
104 EXIT_PROGRAM_DEAD_AND_PID_EXISTS
= 1,
105 EXIT_PROGRAM_DEAD_AND_LOCK_FILE_EXISTS
= 2,
106 EXIT_PROGRAM_NOT_RUNNING
= 3,
107 EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
= 4,
110 static char **arg_types
= NULL
;
111 static char **arg_states
= NULL
;
112 static char **arg_properties
= NULL
;
113 static bool arg_all
= false;
114 static enum dependency
{
120 } arg_dependency
= DEPENDENCY_FORWARD
;
121 static const char *arg_job_mode
= "replace";
122 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
123 static bool arg_wait
= false;
124 static bool arg_no_block
= false;
125 static bool arg_no_legend
= false;
126 static bool arg_no_pager
= false;
127 static bool arg_no_wtmp
= false;
128 static bool arg_no_sync
= false;
129 static bool arg_no_wall
= false;
130 static bool arg_no_reload
= false;
131 static bool arg_value
= false;
132 static bool arg_show_types
= false;
133 static bool arg_ignore_inhibitors
= false;
134 static bool arg_dry
= false;
135 static bool arg_quiet
= false;
136 static bool arg_full
= false;
137 static bool arg_recursive
= false;
138 static int arg_force
= 0;
139 static bool arg_ask_password
= false;
140 static bool arg_runtime
= false;
141 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
142 static char **arg_wall
= NULL
;
143 static const char *arg_kill_who
= NULL
;
144 static int arg_signal
= SIGTERM
;
145 static char *arg_root
= NULL
;
146 static usec_t arg_when
= 0;
147 static char *argv_cmdline
= NULL
;
168 ACTION_CANCEL_SHUTDOWN
,
171 } arg_action
= ACTION_SYSTEMCTL
;
172 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
173 static const char *arg_host
= NULL
;
174 static unsigned arg_lines
= 10;
175 static OutputMode arg_output
= OUTPUT_SHORT
;
176 static bool arg_plain
= false;
177 static bool arg_firmware_setup
= false;
178 static bool arg_now
= false;
179 static bool arg_jobs_before
= false;
180 static bool arg_jobs_after
= false;
182 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
183 static int trivial_method(int argc
, char *argv
[], void *userdata
);
184 static int halt_now(enum action a
);
185 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
187 static bool original_stdout_is_tty
;
189 typedef enum BusFocus
{
190 BUS_FULL
, /* The full bus indicated via --system or --user */
191 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
195 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
197 static UnitFileFlags
args_to_flags(void) {
198 return (arg_runtime
? UNIT_FILE_RUNTIME
: 0) |
199 (arg_force
? UNIT_FILE_FORCE
: 0);
202 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
205 assert(focus
< _BUS_FOCUS_MAX
);
208 /* We only go directly to the manager, if we are using a local transport */
209 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
212 if (getenv_bool("SYSTEMCTL_FORCE_BUS") > 0)
215 if (!busses
[focus
]) {
218 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
220 if (!user
&& sd_booted() <= 0) {
221 /* Print a friendly message when the local system is actually not running systemd as PID 1. */
222 log_error("System has not been booted with systemd as init system (PID 1). Can't operate.");
226 if (focus
== BUS_MANAGER
)
227 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
229 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
231 return log_error_errno(r
, "Failed to connect to bus: %m");
233 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
236 *ret
= busses
[focus
];
240 static void release_busses(void) {
243 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
244 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
247 static int map_string_no_copy(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
249 const char **p
= userdata
;
252 r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &s
);
262 static void ask_password_agent_open_if_enabled(void) {
264 /* Open the password agent as a child process if necessary */
266 if (!arg_ask_password
)
269 if (arg_scope
!= UNIT_FILE_SYSTEM
)
272 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
275 ask_password_agent_open();
278 static void polkit_agent_open_maybe(void) {
279 /* Open the polkit agent as a child process if necessary */
281 if (arg_scope
!= UNIT_FILE_SYSTEM
)
284 polkit_agent_open_if_enabled(arg_transport
, arg_ask_password
);
287 static OutputFlags
get_output_flags(void) {
289 arg_all
* OUTPUT_SHOW_ALL
|
290 (arg_full
|| !on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
291 colors_enabled() * OUTPUT_COLOR
|
292 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
295 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
298 if (!sd_bus_error_is_set(error
))
301 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
302 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
303 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
304 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
305 return EXIT_NOPERMISSION
;
307 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
308 return EXIT_NOTINSTALLED
;
310 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
311 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
312 return EXIT_NOTIMPLEMENTED
;
314 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
315 return EXIT_NOTCONFIGURED
;
323 static bool install_client_side(void) {
325 /* Decides when to execute enable/disable/... operations
326 * client-side rather than server-side. */
328 if (running_in_chroot() > 0)
331 if (sd_booted() <= 0)
334 if (!isempty(arg_root
))
337 if (arg_scope
== UNIT_FILE_GLOBAL
)
340 /* Unsupported environment variable, mostly for debugging purposes */
341 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
347 static int compare_unit_info(const void *a
, const void *b
) {
348 const UnitInfo
*u
= a
, *v
= b
;
352 /* First, order by machine */
353 if (!u
->machine
&& v
->machine
)
355 if (u
->machine
&& !v
->machine
)
357 if (u
->machine
&& v
->machine
) {
358 r
= strcasecmp(u
->machine
, v
->machine
);
363 /* Second, order by unit type */
364 d1
= strrchr(u
->id
, '.');
365 d2
= strrchr(v
->id
, '.');
367 r
= strcasecmp(d1
, d2
);
372 /* Third, order by name */
373 return strcasecmp(u
->id
, v
->id
);
376 static const char* unit_type_suffix(const char *name
) {
379 dot
= strrchr(name
, '.');
386 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
389 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
392 if (arg_types
&& !strv_find(arg_types
, unit_type_suffix(u
->id
)))
398 /* Note that '--all' is not purely a state filter, but also a
399 * filter that hides units that "follow" other units (which is
400 * used for device units that appear under different names). */
401 if (!isempty(u
->following
))
404 if (!strv_isempty(arg_states
))
407 /* By default show all units except the ones in inactive
408 * state and with no pending job */
412 if (streq(u
->active_state
, "inactive"))
418 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
419 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
, max_desc_len
;
421 unsigned n_shown
= 0;
424 max_id_len
= strlen("UNIT");
425 load_len
= strlen("LOAD");
426 active_len
= strlen("ACTIVE");
427 sub_len
= strlen("SUB");
428 job_len
= strlen("JOB");
429 max_desc_len
= strlen("DESCRIPTION");
431 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
432 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
433 load_len
= MAX(load_len
, strlen(u
->load_state
));
434 active_len
= MAX(active_len
, strlen(u
->active_state
));
435 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
436 max_desc_len
= MAX(max_desc_len
, strlen(u
->description
));
438 if (u
->job_id
!= 0) {
439 job_len
= MAX(job_len
, strlen(u
->job_type
));
443 if (!arg_no_legend
&&
444 (streq(u
->active_state
, "failed") ||
445 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
449 if (!arg_full
&& original_stdout_is_tty
) {
452 id_len
= MIN(max_id_len
, 25u); /* as much as it needs, but at most 25 for now */
453 basic_len
= circle_len
+ 1 + id_len
+ 1 + load_len
+ 1 + active_len
+ 1 + sub_len
+ 1;
456 basic_len
+= job_len
+ 1;
458 if (basic_len
< (unsigned) columns()) {
459 unsigned extra_len
, incr
;
460 extra_len
= columns() - basic_len
;
462 /* Either UNIT already got 25, or is fully satisfied.
463 * Grant up to 25 to DESC now. */
464 incr
= MIN(extra_len
, 25u);
468 /* Of the remainder give as much as the ID needs to the ID, and give the rest to the
469 * description but not more than it needs. */
471 incr
= MIN(max_id_len
- id_len
, extra_len
);
473 desc_len
+= MIN(extra_len
- incr
, max_desc_len
- desc_len
);
479 desc_len
= max_desc_len
;
482 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
483 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
484 const char *on_underline
= "", *off_underline
= "";
485 const char *on_loaded
= "", *off_loaded
= "";
486 const char *on_active
= "", *off_active
= "";
487 const char *on_circle
= "", *off_circle
= "";
489 bool circle
= false, underline
= false;
491 if (!n_shown
&& !arg_no_legend
) {
496 printf("%s%-*s %-*s %-*s %-*s ",
500 active_len
, "ACTIVE",
504 printf("%-*s ", job_len
, "JOB");
508 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
515 if (u
+ 1 < unit_infos
+ c
&&
516 !streq(unit_type_suffix(u
->id
), unit_type_suffix((u
+ 1)->id
))) {
517 on_underline
= ansi_underline();
518 off_underline
= ansi_normal();
522 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
523 on_circle
= ansi_highlight_yellow();
524 off_circle
= ansi_normal();
526 on_loaded
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
527 off_loaded
= underline
? on_underline
: ansi_normal();
528 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
529 on_circle
= ansi_highlight_red();
530 off_circle
= ansi_normal();
532 on_active
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
533 off_active
= underline
? on_underline
: ansi_normal();
537 j
= strjoin(u
->machine
, ":", u
->id
);
546 e
= ellipsize(id
, id_len
, 33);
554 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
556 printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
558 on_active
, id_len
, id
, off_active
,
559 on_loaded
, load_len
, u
->load_state
, off_loaded
,
560 on_active
, active_len
, u
->active_state
,
561 sub_len
, u
->sub_state
, off_active
,
562 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
566 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
571 if (!arg_no_legend
) {
572 const char *on
, *off
;
576 "LOAD = Reflects whether the unit definition was properly loaded.\n"
577 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
578 "SUB = The low-level unit activation state, values depend on unit type.");
579 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
580 on
= ansi_highlight();
583 on
= ansi_highlight_red();
588 printf("%s%u loaded units listed.%s\n"
589 "To show all installed unit files use 'systemctl list-unit-files'.\n",
592 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
593 "To show all installed unit files use 'systemctl list-unit-files'.\n",
600 static int get_unit_list(
604 UnitInfo
**unit_infos
,
606 sd_bus_message
**_reply
) {
608 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
609 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
610 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
614 bool fallback
= false;
620 r
= sd_bus_message_new_method_call(
623 "org.freedesktop.systemd1",
624 "/org/freedesktop/systemd1",
625 "org.freedesktop.systemd1.Manager",
626 "ListUnitsByPatterns");
628 return bus_log_create_error(r
);
630 r
= sd_bus_message_append_strv(m
, arg_states
);
632 return bus_log_create_error(r
);
634 r
= sd_bus_message_append_strv(m
, patterns
);
636 return bus_log_create_error(r
);
638 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
639 if (r
< 0 && (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
) ||
640 sd_bus_error_has_name(&error
, SD_BUS_ERROR_ACCESS_DENIED
))) {
641 /* Fallback to legacy ListUnitsFiltered method */
643 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
644 m
= sd_bus_message_unref(m
);
645 sd_bus_error_free(&error
);
647 r
= sd_bus_message_new_method_call(
650 "org.freedesktop.systemd1",
651 "/org/freedesktop/systemd1",
652 "org.freedesktop.systemd1.Manager",
653 "ListUnitsFiltered");
655 return bus_log_create_error(r
);
657 r
= sd_bus_message_append_strv(m
, arg_states
);
659 return bus_log_create_error(r
);
661 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
664 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
666 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
668 return bus_log_parse_error(r
);
670 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
673 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
676 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
679 (*unit_infos
)[c
++] = u
;
682 return bus_log_parse_error(r
);
684 r
= sd_bus_message_exit_container(reply
);
686 return bus_log_parse_error(r
);
694 static void message_set_freep(Set
**set
) {
697 while ((m
= set_steal_first(*set
)))
698 sd_bus_message_unref(m
);
703 static int get_unit_list_recursive(
706 UnitInfo
**_unit_infos
,
710 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
711 _cleanup_(message_set_freep
) Set
*replies
;
712 sd_bus_message
*reply
;
720 replies
= set_new(NULL
);
724 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
728 r
= set_put(replies
, reply
);
730 sd_bus_message_unref(reply
);
735 _cleanup_strv_free_
char **machines
= NULL
;
738 r
= sd_get_machine_names(&machines
);
740 return log_error_errno(r
, "Failed to get machine names: %m");
742 STRV_FOREACH(i
, machines
) {
743 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
746 r
= sd_bus_open_system_machine(&container
, *i
);
748 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
752 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
758 r
= set_put(replies
, reply
);
760 sd_bus_message_unref(reply
);
765 *_machines
= machines
;
770 *_unit_infos
= unit_infos
;
779 static int list_units(int argc
, char *argv
[], void *userdata
) {
780 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
781 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
782 _cleanup_strv_free_
char **machines
= NULL
;
786 r
= acquire_bus(BUS_MANAGER
, &bus
);
790 pager_open(arg_no_pager
, false);
792 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
796 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
797 return output_units_list(unit_infos
, r
);
800 static int get_triggered_units(
805 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
812 r
= sd_bus_get_property_strv(
814 "org.freedesktop.systemd1",
816 "org.freedesktop.systemd1.Unit",
821 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
826 static int get_listening(
828 const char* unit_path
,
831 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
832 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
833 const char *type
, *path
;
836 r
= sd_bus_get_property(
838 "org.freedesktop.systemd1",
840 "org.freedesktop.systemd1.Socket",
846 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
848 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
850 return bus_log_parse_error(r
);
852 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
854 r
= strv_extend(listening
, type
);
858 r
= strv_extend(listening
, path
);
865 return bus_log_parse_error(r
);
867 r
= sd_bus_message_exit_container(reply
);
869 return bus_log_parse_error(r
);
881 /* Note: triggered is a list here, although it almost certainly
882 * will always be one unit. Nevertheless, dbus API allows for multiple
883 * values, so let's follow that. */
886 /* The strv above is shared. free is set only in the first one. */
890 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
896 if (!a
->machine
&& b
->machine
)
898 if (a
->machine
&& !b
->machine
)
900 if (a
->machine
&& b
->machine
) {
901 o
= strcasecmp(a
->machine
, b
->machine
);
906 o
= strcmp(a
->path
, b
->path
);
908 o
= strcmp(a
->type
, b
->type
);
913 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
914 struct socket_info
*s
;
915 unsigned pathlen
= strlen("LISTEN"),
916 typelen
= strlen("TYPE") * arg_show_types
,
917 socklen
= strlen("UNIT"),
918 servlen
= strlen("ACTIVATES");
919 const char *on
, *off
;
921 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
925 socklen
= MAX(socklen
, strlen(s
->id
));
927 typelen
= MAX(typelen
, strlen(s
->type
));
928 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
930 STRV_FOREACH(a
, s
->triggered
)
931 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
932 servlen
= MAX(servlen
, tmp
);
937 printf("%-*s %-*.*s%-*s %s\n",
939 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
943 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
944 _cleanup_free_
char *j
= NULL
;
949 j
= strjoin(s
->machine
, ":", s
->path
);
957 printf("%-*s %-*s %-*s",
958 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
961 pathlen
, path
, socklen
, s
->id
);
962 STRV_FOREACH(a
, s
->triggered
)
964 a
== s
->triggered
? "" : ",", *a
);
968 on
= ansi_highlight();
973 on
= ansi_highlight_red();
977 if (!arg_no_legend
) {
978 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
980 printf("Pass --all to see loaded but inactive sockets, too.\n");
986 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
987 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
988 _cleanup_strv_free_
char **machines
= NULL
;
989 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
990 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
992 struct socket_info
*s
;
998 r
= acquire_bus(BUS_MANAGER
, &bus
);
1002 pager_open(arg_no_pager
, false);
1004 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1008 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1009 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
1012 if (!endswith(u
->id
, ".socket"))
1015 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1019 c
= get_listening(bus
, u
->unit_path
, &listening
);
1025 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
1030 for (i
= 0; i
< c
; i
++)
1031 socket_infos
[cs
+ i
] = (struct socket_info
) {
1032 .machine
= u
->machine
,
1034 .type
= listening
[i
*2],
1035 .path
= listening
[i
*2 + 1],
1036 .triggered
= triggered
,
1037 .own_triggered
= i
==0,
1040 /* from this point on we will cleanup those socket_infos */
1043 listening
= triggered
= NULL
; /* avoid cleanup */
1046 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
1047 (__compar_fn_t
) socket_info_compare
);
1049 output_sockets_list(socket_infos
, cs
);
1052 assert(cs
== 0 || socket_infos
);
1053 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
1056 if (s
->own_triggered
)
1057 strv_free(s
->triggered
);
1063 static int get_next_elapse(
1066 dual_timestamp
*next
) {
1068 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1076 r
= sd_bus_get_property_trivial(
1078 "org.freedesktop.systemd1",
1080 "org.freedesktop.systemd1.Timer",
1081 "NextElapseUSecMonotonic",
1086 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1088 r
= sd_bus_get_property_trivial(
1090 "org.freedesktop.systemd1",
1092 "org.freedesktop.systemd1.Timer",
1093 "NextElapseUSecRealtime",
1098 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1104 static int get_last_trigger(
1109 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1116 r
= sd_bus_get_property_trivial(
1118 "org.freedesktop.systemd1",
1120 "org.freedesktop.systemd1.Timer",
1126 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1132 const char* machine
;
1135 usec_t last_trigger
;
1139 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1145 if (!a
->machine
&& b
->machine
)
1147 if (a
->machine
&& !b
->machine
)
1149 if (a
->machine
&& b
->machine
) {
1150 o
= strcasecmp(a
->machine
, b
->machine
);
1155 if (a
->next_elapse
< b
->next_elapse
)
1157 if (a
->next_elapse
> b
->next_elapse
)
1160 return strcmp(a
->id
, b
->id
);
1163 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1164 struct timer_info
*t
;
1166 nextlen
= strlen("NEXT"),
1167 leftlen
= strlen("LEFT"),
1168 lastlen
= strlen("LAST"),
1169 passedlen
= strlen("PASSED"),
1170 unitlen
= strlen("UNIT"),
1171 activatelen
= strlen("ACTIVATES");
1173 const char *on
, *off
;
1175 assert(timer_infos
|| n
== 0);
1177 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1181 if (t
->next_elapse
> 0) {
1182 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1184 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1185 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1187 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1188 leftlen
= MAX(leftlen
, strlen(trel
));
1191 if (t
->last_trigger
> 0) {
1192 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1194 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1195 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1197 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1198 passedlen
= MAX(passedlen
, strlen(trel
));
1201 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1203 STRV_FOREACH(a
, t
->triggered
)
1204 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1206 activatelen
= MAX(activatelen
, ul
);
1211 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1215 passedlen
, "PASSED",
1219 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1220 _cleanup_free_
char *j
= NULL
;
1222 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1223 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1226 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1227 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1229 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1230 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1233 j
= strjoin(t
->machine
, ":", t
->id
);
1240 printf("%-*s %-*s %-*s %-*s %-*s",
1241 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1243 STRV_FOREACH(a
, t
->triggered
)
1245 a
== t
->triggered
? "" : ",", *a
);
1249 on
= ansi_highlight();
1250 off
= ansi_normal();
1254 on
= ansi_highlight_red();
1255 off
= ansi_normal();
1258 if (!arg_no_legend
) {
1259 printf("%s%u timers listed.%s\n", on
, n
, off
);
1261 printf("Pass --all to see loaded but inactive timers, too.\n");
1267 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1273 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1276 if (next
->monotonic
> nw
->monotonic
)
1277 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1279 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1281 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1282 next_elapse
= MIN(converted
, next
->realtime
);
1284 next_elapse
= converted
;
1287 next_elapse
= next
->realtime
;
1292 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1293 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1294 _cleanup_strv_free_
char **machines
= NULL
;
1295 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1296 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1297 struct timer_info
*t
;
1305 r
= acquire_bus(BUS_MANAGER
, &bus
);
1309 pager_open(arg_no_pager
, false);
1311 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1315 dual_timestamp_get(&nw
);
1317 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1318 _cleanup_strv_free_
char **triggered
= NULL
;
1319 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1322 if (!endswith(u
->id
, ".timer"))
1325 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1329 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1333 get_last_trigger(bus
, u
->unit_path
, &last
);
1335 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1340 m
= calc_next_elapse(&nw
, &next
);
1342 timer_infos
[c
++] = (struct timer_info
) {
1343 .machine
= u
->machine
,
1346 .last_trigger
= last
,
1347 .triggered
= triggered
,
1350 triggered
= NULL
; /* avoid cleanup */
1353 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1354 (__compar_fn_t
) timer_info_compare
);
1356 output_timers_list(timer_infos
, c
);
1359 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1360 strv_free(t
->triggered
);
1365 static int compare_unit_file_list(const void *a
, const void *b
) {
1366 const char *d1
, *d2
;
1367 const UnitFileList
*u
= a
, *v
= b
;
1369 d1
= strrchr(u
->path
, '.');
1370 d2
= strrchr(v
->path
, '.');
1375 r
= strcasecmp(d1
, d2
);
1380 return strcasecmp(basename(u
->path
), basename(v
->path
));
1383 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1386 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1389 if (!strv_isempty(arg_types
)) {
1392 dot
= strrchr(u
->path
, '.');
1396 if (!strv_find(arg_types
, dot
+1))
1400 if (!strv_isempty(states
) &&
1401 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1407 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1408 unsigned max_id_len
, id_cols
, state_cols
;
1409 const UnitFileList
*u
;
1411 max_id_len
= strlen("UNIT FILE");
1412 state_cols
= strlen("STATE");
1414 for (u
= units
; u
< units
+ c
; u
++) {
1415 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1416 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1420 unsigned basic_cols
;
1422 id_cols
= MIN(max_id_len
, 25u);
1423 basic_cols
= 1 + id_cols
+ state_cols
;
1424 if (basic_cols
< (unsigned) columns())
1425 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1427 id_cols
= max_id_len
;
1429 if (!arg_no_legend
&& c
> 0)
1430 printf("%s%-*s %-*s%s\n",
1432 id_cols
, "UNIT FILE",
1433 state_cols
, "STATE",
1436 for (u
= units
; u
< units
+ c
; u
++) {
1437 const char *on_underline
= NULL
, *on_color
= NULL
, *off
= NULL
, *id
;
1438 _cleanup_free_
char *e
= NULL
;
1441 underline
= u
+ 1 < units
+ c
&&
1442 !streq(unit_type_suffix(u
->path
), unit_type_suffix((u
+ 1)->path
));
1445 on_underline
= ansi_underline();
1447 if (IN_SET(u
->state
,
1449 UNIT_FILE_MASKED_RUNTIME
,
1452 on_color
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
1453 else if (u
->state
== UNIT_FILE_ENABLED
)
1454 on_color
= underline
? ansi_highlight_green_underline() : ansi_highlight_green();
1456 if (on_underline
|| on_color
)
1457 off
= ansi_normal();
1459 id
= basename(u
->path
);
1461 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1463 printf("%s%-*s %s%-*s%s\n",
1464 strempty(on_underline
),
1465 id_cols
, e
? e
: id
,
1466 strempty(on_color
), state_cols
, unit_file_state_to_string(u
->state
), strempty(off
));
1470 printf("\n%u unit files listed.\n", c
);
1473 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1474 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1475 _cleanup_free_ UnitFileList
*units
= NULL
;
1482 bool fallback
= false;
1484 if (install_client_side()) {
1490 h
= hashmap_new(&string_hash_ops
);
1494 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1496 unit_file_list_free(h
);
1497 return log_error_errno(r
, "Failed to get unit file list: %m");
1500 n_units
= hashmap_size(h
);
1502 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1504 unit_file_list_free(h
);
1508 HASHMAP_FOREACH(u
, h
, i
) {
1509 if (!output_show_unit_file(u
, NULL
, NULL
))
1516 assert(c
<= n_units
);
1521 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1522 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1525 r
= acquire_bus(BUS_MANAGER
, &bus
);
1529 r
= sd_bus_message_new_method_call(
1532 "org.freedesktop.systemd1",
1533 "/org/freedesktop/systemd1",
1534 "org.freedesktop.systemd1.Manager",
1535 "ListUnitFilesByPatterns");
1537 return bus_log_create_error(r
);
1539 r
= sd_bus_message_append_strv(m
, arg_states
);
1541 return bus_log_create_error(r
);
1543 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1545 return bus_log_create_error(r
);
1547 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1548 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1549 /* Fallback to legacy ListUnitFiles method */
1551 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1552 m
= sd_bus_message_unref(m
);
1553 sd_bus_error_free(&error
);
1555 r
= sd_bus_message_new_method_call(
1558 "org.freedesktop.systemd1",
1559 "/org/freedesktop/systemd1",
1560 "org.freedesktop.systemd1.Manager",
1563 return bus_log_create_error(r
);
1565 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1568 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1570 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1572 return bus_log_parse_error(r
);
1574 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1576 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1579 units
[c
] = (struct UnitFileList
) {
1581 unit_file_state_from_string(state
)
1584 if (output_show_unit_file(&units
[c
],
1585 fallback
? arg_states
: NULL
,
1586 fallback
? strv_skip(argv
, 1) : NULL
))
1591 return bus_log_parse_error(r
);
1593 r
= sd_bus_message_exit_container(reply
);
1595 return bus_log_parse_error(r
);
1598 pager_open(arg_no_pager
, false);
1600 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1601 output_unit_file_list(units
, c
);
1603 if (install_client_side())
1604 for (unit
= units
; unit
< units
+ c
; unit
++)
1610 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1611 _cleanup_free_
char *n
= NULL
;
1612 size_t max_len
= MAX(columns(),20u);
1618 for (i
= level
- 1; i
>= 0; i
--) {
1620 if (len
> max_len
- 3 && !arg_full
) {
1621 printf("%s...\n",max_len
% 2 ? "" : " ");
1624 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1628 if (len
> max_len
- 3 && !arg_full
) {
1629 printf("%s...\n",max_len
% 2 ? "" : " ");
1633 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1637 printf("%s\n", name
);
1641 n
= ellipsize(name
, max_len
-len
, 100);
1649 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1651 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1652 [DEPENDENCY_FORWARD
] = "Requires\0"
1657 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1662 [DEPENDENCY_AFTER
] = "After\0",
1663 [DEPENDENCY_BEFORE
] = "Before\0",
1666 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1667 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1668 _cleanup_strv_free_
char **ret
= NULL
;
1669 _cleanup_free_
char *path
= NULL
;
1675 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1677 path
= unit_dbus_path_from_name(name
);
1681 r
= sd_bus_call_method(
1683 "org.freedesktop.systemd1",
1685 "org.freedesktop.DBus.Properties",
1689 "s", "org.freedesktop.systemd1.Unit");
1691 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1693 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1695 return bus_log_parse_error(r
);
1697 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1700 r
= sd_bus_message_read(reply
, "s", &prop
);
1702 return bus_log_parse_error(r
);
1704 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1705 r
= sd_bus_message_skip(reply
, "v");
1707 return bus_log_parse_error(r
);
1710 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1712 return bus_log_parse_error(r
);
1714 r
= bus_message_read_strv_extend(reply
, &ret
);
1716 return bus_log_parse_error(r
);
1718 r
= sd_bus_message_exit_container(reply
);
1720 return bus_log_parse_error(r
);
1723 r
= sd_bus_message_exit_container(reply
);
1725 return bus_log_parse_error(r
);
1729 return bus_log_parse_error(r
);
1731 r
= sd_bus_message_exit_container(reply
);
1733 return bus_log_parse_error(r
);
1735 *deps
= strv_uniq(ret
);
1741 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1742 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1744 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1746 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1749 return strcasecmp(*a
, *b
);
1752 static int list_dependencies_one(
1757 unsigned int branches
) {
1759 _cleanup_strv_free_
char **deps
= NULL
;
1767 r
= strv_extend(units
, name
);
1771 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1775 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1777 STRV_FOREACH(c
, deps
) {
1778 if (strv_contains(*units
, *c
)) {
1781 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1791 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1794 (void) get_state_one_unit(bus
, *c
, &active_state
);
1796 switch (active_state
) {
1798 case UNIT_RELOADING
:
1799 case UNIT_ACTIVATING
:
1800 on
= ansi_highlight_green();
1804 case UNIT_DEACTIVATING
:
1809 on
= ansi_highlight_red();
1813 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1816 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1820 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1821 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1828 strv_remove(*units
, name
);
1833 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1834 _cleanup_strv_free_
char **units
= NULL
;
1835 _cleanup_free_
char *unit
= NULL
;
1841 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1843 return log_error_errno(r
, "Failed to mangle unit name: %m");
1847 u
= SPECIAL_DEFAULT_TARGET
;
1849 r
= acquire_bus(BUS_MANAGER
, &bus
);
1853 pager_open(arg_no_pager
, false);
1857 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1860 struct machine_info
{
1864 char *control_group
;
1865 uint32_t n_failed_units
;
1870 static const struct bus_properties_map machine_info_property_map
[] = {
1871 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1872 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1873 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1874 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1875 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1879 static void machine_info_clear(struct machine_info
*info
) {
1884 free(info
->control_group
);
1888 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1894 for (i
= 0; i
< n
; i
++)
1895 machine_info_clear(&machine_infos
[i
]);
1897 free(machine_infos
);
1900 static int compare_machine_info(const void *a
, const void *b
) {
1901 const struct machine_info
*u
= a
, *v
= b
;
1903 if (u
->is_host
!= v
->is_host
)
1904 return u
->is_host
> v
->is_host
? -1 : 1;
1906 return strcasecmp(u
->name
, v
->name
);
1909 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1910 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1916 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1923 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, NULL
, mi
);
1930 static bool output_show_machine(const char *name
, char **patterns
) {
1931 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1934 static int get_machine_list(
1936 struct machine_info
**_machine_infos
,
1939 struct machine_info
*machine_infos
= NULL
;
1940 _cleanup_strv_free_
char **m
= NULL
;
1941 _cleanup_free_
char *hn
= NULL
;
1946 hn
= gethostname_malloc();
1950 if (output_show_machine(hn
, patterns
)) {
1951 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1954 machine_infos
[c
].is_host
= true;
1955 machine_infos
[c
].name
= hn
;
1958 (void) get_machine_properties(bus
, &machine_infos
[c
]);
1962 r
= sd_get_machine_names(&m
);
1964 return log_error_errno(r
, "Failed to get machine list: %m");
1966 STRV_FOREACH(i
, m
) {
1967 _cleanup_free_
char *class = NULL
;
1969 if (!output_show_machine(*i
, patterns
))
1972 sd_machine_get_class(*i
, &class);
1973 if (!streq_ptr(class, "container"))
1976 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1977 free_machines_list(machine_infos
, c
);
1981 machine_infos
[c
].is_host
= false;
1982 machine_infos
[c
].name
= strdup(*i
);
1983 if (!machine_infos
[c
].name
) {
1984 free_machines_list(machine_infos
, c
);
1988 (void) get_machine_properties(NULL
, &machine_infos
[c
]);
1992 *_machine_infos
= machine_infos
;
1996 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1997 struct machine_info
*m
;
2000 namelen
= sizeof("NAME") - 1,
2001 statelen
= sizeof("STATE") - 1,
2002 failedlen
= sizeof("FAILED") - 1,
2003 jobslen
= sizeof("JOBS") - 1;
2005 assert(machine_infos
|| n
== 0);
2007 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2008 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
2009 statelen
= MAX(statelen
, strlen_ptr(m
->state
));
2010 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
2011 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
2013 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
2017 if (!arg_no_legend
) {
2021 printf("%-*s %-*s %-*s %-*s\n",
2024 failedlen
, "FAILED",
2028 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2029 const char *on_state
= "", *off_state
= "";
2030 const char *on_failed
= "", *off_failed
= "";
2031 bool circle
= false;
2033 if (streq_ptr(m
->state
, "degraded")) {
2034 on_state
= ansi_highlight_red();
2035 off_state
= ansi_normal();
2037 } else if (!streq_ptr(m
->state
, "running")) {
2038 on_state
= ansi_highlight_yellow();
2039 off_state
= ansi_normal();
2043 if (m
->n_failed_units
> 0) {
2044 on_failed
= ansi_highlight_red();
2045 off_failed
= ansi_normal();
2047 on_failed
= off_failed
= "";
2050 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
2053 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2054 (int) (namelen
- (sizeof(" (host)")-1)), 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
);
2059 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2060 namelen
, strna(m
->name
),
2061 on_state
, statelen
, strna(m
->state
), off_state
,
2062 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2063 jobslen
, m
->n_jobs
);
2067 printf("\n%u machines listed.\n", n
);
2070 static int list_machines(int argc
, char *argv
[], void *userdata
) {
2071 struct machine_info
*machine_infos
= NULL
;
2075 if (geteuid() != 0) {
2076 log_error("Must be root.");
2080 r
= acquire_bus(BUS_MANAGER
, &bus
);
2084 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2088 pager_open(arg_no_pager
, false);
2090 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2091 output_machines_list(machine_infos
, r
);
2092 free_machines_list(machine_infos
, r
);
2097 static int get_default(int argc
, char *argv
[], void *userdata
) {
2098 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2099 _cleanup_free_
char *_path
= NULL
;
2103 if (install_client_side()) {
2104 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2106 return log_error_errno(r
, "Failed to get default target: %m");
2111 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2114 r
= acquire_bus(BUS_MANAGER
, &bus
);
2118 r
= sd_bus_call_method(
2120 "org.freedesktop.systemd1",
2121 "/org/freedesktop/systemd1",
2122 "org.freedesktop.systemd1.Manager",
2128 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2130 r
= sd_bus_message_read(reply
, "s", &path
);
2132 return bus_log_parse_error(r
);
2136 printf("%s\n", path
);
2141 static int set_default(int argc
, char *argv
[], void *userdata
) {
2142 _cleanup_free_
char *unit
= NULL
;
2143 UnitFileChange
*changes
= NULL
;
2144 unsigned n_changes
= 0;
2150 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2152 return log_error_errno(r
, "Failed to mangle unit name: %m");
2154 if (install_client_side()) {
2155 r
= unit_file_set_default(arg_scope
, UNIT_FILE_FORCE
, arg_root
, unit
, &changes
, &n_changes
);
2156 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2161 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2162 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2165 polkit_agent_open_maybe();
2167 r
= acquire_bus(BUS_MANAGER
, &bus
);
2171 r
= sd_bus_call_method(
2173 "org.freedesktop.systemd1",
2174 "/org/freedesktop/systemd1",
2175 "org.freedesktop.systemd1.Manager",
2181 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2183 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2187 /* Try to reload if enabled */
2189 r
= daemon_reload(argc
, argv
, userdata
);
2195 unit_file_changes_free(changes
, n_changes
);
2200 static int output_waiting_jobs(sd_bus
*bus
, uint32_t id
, const char *method
, const char *prefix
) {
2201 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2202 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2203 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2209 r
= sd_bus_call_method(
2211 "org.freedesktop.systemd1",
2212 "/org/freedesktop/systemd1",
2213 "org.freedesktop.systemd1.Manager",
2219 return log_debug_errno(r
, "Failed to get waiting jobs for job %" PRIu32
, id
);
2221 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2223 return bus_log_parse_error(r
);
2225 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &other_id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0)
2226 printf("%s %u (%s/%s)\n", prefix
, other_id
, name
, type
);
2228 return bus_log_parse_error(r
);
2230 r
= sd_bus_message_exit_container(reply
);
2232 return bus_log_parse_error(r
);
2239 const char *name
, *type
, *state
;
2242 static void output_jobs_list(sd_bus
*bus
, const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2243 unsigned id_len
, unit_len
, type_len
, state_len
;
2244 const struct job_info
*j
;
2245 const char *on
, *off
;
2246 bool shorten
= false;
2248 assert(n
== 0 || jobs
);
2251 if (!arg_no_legend
) {
2252 on
= ansi_highlight_green();
2253 off
= ansi_normal();
2255 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2260 pager_open(arg_no_pager
, false);
2262 id_len
= strlen("JOB");
2263 unit_len
= strlen("UNIT");
2264 type_len
= strlen("TYPE");
2265 state_len
= strlen("STATE");
2267 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2268 uint32_t id
= j
->id
;
2269 assert(j
->name
&& j
->type
&& j
->state
);
2271 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2272 unit_len
= MAX(unit_len
, strlen(j
->name
));
2273 type_len
= MAX(type_len
, strlen(j
->type
));
2274 state_len
= MAX(state_len
, strlen(j
->state
));
2277 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2278 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2283 printf("%*s %-*s %-*s %-*s\n",
2287 state_len
, "STATE");
2289 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2290 _cleanup_free_
char *e
= NULL
;
2292 if (streq(j
->state
, "running")) {
2293 on
= ansi_highlight();
2294 off
= ansi_normal();
2298 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2299 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2301 on
, unit_len
, e
? e
: j
->name
, off
,
2303 on
, state_len
, j
->state
, off
);
2306 output_waiting_jobs(bus
, j
->id
, "GetJobAfter", "\twaiting for job");
2307 if (arg_jobs_before
)
2308 output_waiting_jobs(bus
, j
->id
, "GetJobBefore", "\tblocking job");
2311 if (!arg_no_legend
) {
2312 on
= ansi_highlight();
2313 off
= ansi_normal();
2315 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2319 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2320 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2323 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2324 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2325 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2326 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2327 _cleanup_free_
struct job_info
*jobs
= NULL
;
2333 bool skipped
= false;
2335 r
= acquire_bus(BUS_MANAGER
, &bus
);
2339 r
= sd_bus_call_method(
2341 "org.freedesktop.systemd1",
2342 "/org/freedesktop/systemd1",
2343 "org.freedesktop.systemd1.Manager",
2349 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2351 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2353 return bus_log_parse_error(r
);
2355 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2356 struct job_info job
= { id
, name
, type
, state
};
2358 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2363 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2369 return bus_log_parse_error(r
);
2371 r
= sd_bus_message_exit_container(reply
);
2373 return bus_log_parse_error(r
);
2375 pager_open(arg_no_pager
, false);
2377 output_jobs_list(bus
, jobs
, c
, skipped
);
2381 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2387 return trivial_method(argc
, argv
, userdata
);
2389 r
= acquire_bus(BUS_MANAGER
, &bus
);
2393 polkit_agent_open_maybe();
2395 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2396 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2400 q
= safe_atou32(*name
, &id
);
2402 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2404 q
= sd_bus_call_method(
2406 "org.freedesktop.systemd1",
2407 "/org/freedesktop/systemd1",
2408 "org.freedesktop.systemd1.Manager",
2414 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2423 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2424 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2428 /* We ignore all errors here, since this is used to show a
2431 /* We don't use unit_dbus_path_from_name() directly since we
2432 * don't want to load the unit if it isn't loaded. */
2434 r
= sd_bus_call_method(
2436 "org.freedesktop.systemd1",
2437 "/org/freedesktop/systemd1",
2438 "org.freedesktop.systemd1.Manager",
2446 r
= sd_bus_message_read(reply
, "o", &path
);
2450 r
= sd_bus_get_property_trivial(
2452 "org.freedesktop.systemd1",
2454 "org.freedesktop.systemd1.Unit",
2464 static void warn_unit_file_changed(const char *name
) {
2467 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2468 ansi_highlight_red(),
2471 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2474 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2480 STRV_FOREACH(p
, lp
->search_path
) {
2481 _cleanup_free_
char *path
= NULL
, *lpath
= NULL
;
2484 path
= path_join(NULL
, *p
, unit_name
);
2488 r
= chase_symlinks(path
, arg_root
, 0, &lpath
);
2494 return log_error_errno(r
, "Failed to access path '%s': %m", path
);
2506 static int unit_find_template_path(
2507 const char *unit_name
,
2509 char **fragment_path
,
2512 _cleanup_free_
char *_template
= NULL
;
2515 /* Returns 1 if a fragment was found, 0 if not found, negative on error. */
2517 r
= unit_file_find_path(lp
, unit_name
, fragment_path
);
2519 return r
; /* error or found a real unit */
2521 r
= unit_name_template(unit_name
, &_template
);
2523 return 0; /* not a template, does not exist */
2525 return log_error_errno(r
, "Failed to determine template name: %m");
2527 r
= unit_file_find_path(lp
, _template
, fragment_path
);
2532 *template = _template
;
2538 static int unit_find_paths(
2540 const char *unit_name
,
2542 char **fragment_path
,
2543 char ***dropin_paths
) {
2545 _cleanup_free_
char *path
= NULL
;
2546 _cleanup_strv_free_
char **dropins
= NULL
;
2550 * Finds where the unit is defined on disk. Returns 0 if the unit
2551 * is not found. Returns 1 if it is found, and sets
2552 * - the path to the unit in *path, if it exists on disk,
2553 * - and a strv of existing drop-ins in *dropins,
2554 * if the arg is not NULL and any dropins were found.
2558 assert(fragment_path
);
2561 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2562 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2563 _cleanup_free_
char *unit
= NULL
;
2565 unit
= unit_dbus_path_from_name(unit_name
);
2569 r
= sd_bus_get_property_string(
2571 "org.freedesktop.systemd1",
2573 "org.freedesktop.systemd1.Unit",
2578 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2581 r
= sd_bus_get_property_strv(
2583 "org.freedesktop.systemd1",
2585 "org.freedesktop.systemd1.Unit",
2590 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2593 _cleanup_set_free_ Set
*names
= NULL
;
2594 _cleanup_free_
char *template = NULL
;
2596 names
= set_new(NULL
);
2600 r
= unit_find_template_path(unit_name
, lp
, &path
, &template);
2605 /* We found the unit file. If we followed symlinks, this name might be
2606 * different then the unit_name with started with. Look for dropins matching
2607 * that "final" name. */
2608 r
= set_put(names
, basename(path
));
2610 /* No unit file, let's look for dropins matching the original name.
2611 * systemd has fairly complicated rules (based on unit type and provenience),
2612 * which units are allowed not to have the main unit file. We err on the
2613 * side of including too many files, and always try to load dropins. */
2614 r
= set_put(names
, unit_name
);
2616 /* The cases where we allow a unit to exist without the main file are
2617 * never valid for templates. Don't try to load dropins in this case. */
2621 return log_error_errno(r
, "Failed to add unit name: %m");
2624 r
= unit_file_find_dropin_conf_paths(arg_root
, lp
->search_path
,
2625 NULL
, names
, &dropins
);
2633 if (!isempty(path
)) {
2634 *fragment_path
= path
;
2639 if (dropin_paths
&& !strv_isempty(dropins
)) {
2640 *dropin_paths
= dropins
;
2645 if (r
== 0 && !arg_force
)
2646 log_error("No files found for %s.", unit_name
);
2651 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2652 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2653 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2654 _cleanup_free_
char *buf
= NULL
;
2655 UnitActiveState state
;
2660 assert(active_state
);
2662 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2664 r
= sd_bus_call_method(
2666 "org.freedesktop.systemd1",
2667 "/org/freedesktop/systemd1",
2668 "org.freedesktop.systemd1.Manager",
2674 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2675 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2677 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2678 * considered inactive. */
2679 state
= UNIT_INACTIVE
;
2682 r
= sd_bus_message_read(reply
, "o", &path
);
2684 return bus_log_parse_error(r
);
2686 r
= sd_bus_get_property_string(
2688 "org.freedesktop.systemd1",
2690 "org.freedesktop.systemd1.Unit",
2695 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2697 state
= unit_active_state_from_string(buf
);
2698 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2699 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2704 *active_state
= state
;
2708 static int check_triggering_units(
2712 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2713 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2714 _cleanup_strv_free_
char **triggered_by
= NULL
;
2715 bool print_warning_label
= true;
2716 UnitActiveState active_state
;
2720 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2722 return log_error_errno(r
, "Failed to mangle unit name: %m");
2724 path
= unit_dbus_path_from_name(n
);
2728 r
= sd_bus_get_property_string(
2730 "org.freedesktop.systemd1",
2732 "org.freedesktop.systemd1.Unit",
2737 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2739 if (streq(load_state
, "masked"))
2742 r
= sd_bus_get_property_strv(
2744 "org.freedesktop.systemd1",
2746 "org.freedesktop.systemd1.Unit",
2751 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2753 STRV_FOREACH(i
, triggered_by
) {
2754 r
= get_state_one_unit(bus
, *i
, &active_state
);
2758 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2761 if (print_warning_label
) {
2762 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2763 print_warning_label
= false;
2766 log_warning(" %s", *i
);
2772 static const struct {
2775 } unit_actions
[] = {
2776 { "start", "StartUnit" },
2777 { "stop", "StopUnit" },
2778 { "condstop", "StopUnit" },
2779 { "reload", "ReloadUnit" },
2780 { "restart", "RestartUnit" },
2781 { "try-restart", "TryRestartUnit" },
2782 { "condrestart", "TryRestartUnit" },
2783 { "reload-or-restart", "ReloadOrRestartUnit" },
2784 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2785 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2786 { "condreload", "ReloadOrTryRestartUnit" },
2787 { "force-reload", "ReloadOrTryRestartUnit" }
2790 static const char *verb_to_method(const char *verb
) {
2793 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2794 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2795 return unit_actions
[i
].method
;
2800 static const char *method_to_verb(const char *method
) {
2803 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2804 if (streq_ptr(unit_actions
[i
].method
, method
))
2805 return unit_actions
[i
].verb
;
2817 static void wait_context_free(WaitContext
*c
) {
2818 c
->match
= sd_bus_slot_unref(c
->match
);
2819 c
->event
= sd_event_unref(c
->event
);
2820 c
->unit_paths
= set_free_free(c
->unit_paths
);
2823 static int on_properties_changed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
2824 WaitContext
*c
= userdata
;
2828 path
= sd_bus_message_get_path(m
);
2829 if (!set_contains(c
->unit_paths
, path
))
2832 /* Check if ActiveState changed to inactive/failed */
2833 /* (s interface, a{sv} changed_properties, as invalidated_properties) */
2834 r
= sd_bus_message_skip(m
, "s");
2836 return bus_log_parse_error(r
);
2838 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
2840 return bus_log_parse_error(r
);
2842 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
2845 r
= sd_bus_message_read(m
, "s", &s
);
2847 return bus_log_parse_error(r
);
2849 if (streq(s
, "ActiveState")) {
2852 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, "s");
2854 return bus_log_parse_error(r
);
2856 r
= sd_bus_message_read(m
, "s", &s
);
2858 return bus_log_parse_error(r
);
2860 is_failed
= streq(s
, "failed");
2861 if (streq(s
, "inactive") || is_failed
) {
2862 log_debug("%s became %s, dropping from --wait tracking", path
, s
);
2863 free(set_remove(c
->unit_paths
, path
));
2864 c
->any_failed
= c
->any_failed
|| is_failed
;
2866 log_debug("ActiveState on %s changed to %s", path
, s
);
2868 break; /* no need to dissect the rest of the message */
2870 /* other property */
2871 r
= sd_bus_message_skip(m
, "v");
2873 return bus_log_parse_error(r
);
2875 r
= sd_bus_message_exit_container(m
);
2877 return bus_log_parse_error(r
);
2880 return bus_log_parse_error(r
);
2882 if (set_isempty(c
->unit_paths
))
2883 sd_event_exit(c
->event
, EXIT_SUCCESS
);
2888 static int start_unit_one(
2893 sd_bus_error
*error
,
2895 WaitContext
*wait_context
) {
2897 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2907 _cleanup_free_
char *unit_path
= NULL
;
2910 log_debug("Watching for property changes of %s", name
);
2911 r
= sd_bus_call_method(
2913 "org.freedesktop.systemd1",
2914 "/org/freedesktop/systemd1",
2915 "org.freedesktop.systemd1.Manager",
2921 return log_error_errno(r
, "Failed to RefUnit %s: %s", name
, bus_error_message(error
, r
));
2923 unit_path
= unit_dbus_path_from_name(name
);
2927 r
= set_put_strdup(wait_context
->unit_paths
, unit_path
);
2929 return log_error_errno(r
, "Failed to add unit path %s to set: %m", unit_path
);
2931 mt
= strjoina("type='signal',"
2932 "interface='org.freedesktop.DBus.Properties',"
2933 "path='", unit_path
, "',"
2934 "member='PropertiesChanged'");
2935 r
= sd_bus_add_match(bus
, &wait_context
->match
, mt
, on_properties_changed
, wait_context
);
2937 return log_error_errno(r
, "Failed to add match for PropertiesChanged signal: %m");
2940 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2942 r
= sd_bus_call_method(
2944 "org.freedesktop.systemd1",
2945 "/org/freedesktop/systemd1",
2946 "org.freedesktop.systemd1.Manager",
2954 /* There's always a fallback possible for legacy actions. */
2955 if (arg_action
!= ACTION_SYSTEMCTL
)
2958 verb
= method_to_verb(method
);
2960 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2962 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2963 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2964 log_error("See %s logs and 'systemctl%s status%s %s' for details.",
2965 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2966 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2967 name
[0] == '-' ? " --" : "",
2973 r
= sd_bus_message_read(reply
, "o", &path
);
2975 return bus_log_parse_error(r
);
2977 if (need_daemon_reload(bus
, name
) > 0)
2978 warn_unit_file_changed(name
);
2981 log_debug("Adding %s to the set", path
);
2982 r
= bus_wait_for_jobs_add(w
, path
);
2990 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2991 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2998 STRV_FOREACH(name
, names
) {
3002 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
3004 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
3006 return log_error_errno(r
, "Failed to mangle name: %m");
3008 if (string_is_glob(t
))
3009 r
= strv_consume(&globs
, t
);
3011 r
= strv_consume(&mangled
, t
);
3016 /* Query the manager only if any of the names are a glob, since
3017 * this is fairly expensive */
3018 if (!strv_isempty(globs
)) {
3019 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3020 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
3021 size_t allocated
, n
;
3023 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
3027 n
= strv_length(mangled
);
3030 for (i
= 0; i
< r
; i
++) {
3031 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
3034 mangled
[n
] = strdup(unit_infos
[i
].id
);
3038 mangled
[++n
] = NULL
;
3043 mangled
= NULL
; /* do not free */
3048 static const struct {
3052 } action_table
[_ACTION_MAX
] = {
3053 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
3054 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
3055 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
3056 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
3057 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3058 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3059 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3060 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
3061 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
3062 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
3063 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
3064 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
3065 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
3066 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
3067 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
3070 static enum action
verb_to_action(const char *verb
) {
3073 for (i
= 0; i
< _ACTION_MAX
; i
++)
3074 if (streq_ptr(action_table
[i
].verb
, verb
))
3077 return _ACTION_INVALID
;
3080 static int start_unit(int argc
, char *argv
[], void *userdata
) {
3081 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
3082 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
3083 _cleanup_strv_free_
char **names
= NULL
;
3085 _cleanup_(wait_context_free
) WaitContext wait_context
= {};
3089 if (arg_wait
&& !STR_IN_SET(argv
[0], "start", "restart")) {
3090 log_error("--wait may only be used with the 'start' or 'restart' commands.");
3094 /* we cannot do sender tracking on the private bus, so we need the full
3095 * one for RefUnit to implement --wait */
3096 r
= acquire_bus(arg_wait
? BUS_FULL
: BUS_MANAGER
, &bus
);
3100 ask_password_agent_open_if_enabled();
3101 polkit_agent_open_maybe();
3103 if (arg_action
== ACTION_SYSTEMCTL
) {
3106 action
= verb_to_action(argv
[0]);
3108 if (action
!= _ACTION_INVALID
) {
3109 method
= "StartUnit";
3110 mode
= action_table
[action
].mode
;
3111 one_name
= action_table
[action
].target
;
3113 if (streq(argv
[0], "isolate")) {
3114 method
= "StartUnit";
3119 method
= verb_to_method(argv
[0]);
3120 mode
= arg_job_mode
;
3125 assert(arg_action
>= 0 && arg_action
< _ACTION_MAX
);
3126 assert(action_table
[arg_action
].target
);
3127 assert(action_table
[arg_action
].mode
);
3129 method
= "StartUnit";
3130 mode
= action_table
[arg_action
].mode
;
3131 one_name
= action_table
[arg_action
].target
;
3135 names
= strv_new(one_name
, NULL
);
3137 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
3139 return log_error_errno(r
, "Failed to expand names: %m");
3142 if (!arg_no_block
) {
3143 r
= bus_wait_for_jobs_new(bus
, &w
);
3145 return log_error_errno(r
, "Could not watch jobs: %m");
3149 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3151 wait_context
.unit_paths
= set_new(&string_hash_ops
);
3152 if (!wait_context
.unit_paths
)
3155 r
= sd_bus_call_method(
3157 "org.freedesktop.systemd1",
3158 "/org/freedesktop/systemd1",
3159 "org.freedesktop.systemd1.Manager",
3164 return log_error_errno(r
, "Failed to enable subscription: %s", bus_error_message(&error
, r
));
3165 r
= sd_event_default(&wait_context
.event
);
3167 return log_error_errno(r
, "Failed to allocate event loop: %m");
3168 r
= sd_bus_attach_event(bus
, wait_context
.event
, 0);
3170 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
3173 STRV_FOREACH(name
, names
) {
3174 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3177 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
, arg_wait
? &wait_context
: NULL
);
3178 if (r
>= 0 && q
< 0)
3179 r
= translate_bus_error_to_exit_status(q
, &error
);
3182 if (!arg_no_block
) {
3183 int q
, arg_count
= 0;
3184 const char* extra_args
[4] = {};
3186 if (arg_scope
!= UNIT_FILE_SYSTEM
)
3187 extra_args
[arg_count
++] = "--user";
3189 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
3190 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
3191 extra_args
[arg_count
++] = "-H";
3192 extra_args
[arg_count
++] = arg_host
;
3193 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
3194 extra_args
[arg_count
++] = "-M";
3195 extra_args
[arg_count
++] = arg_host
;
3198 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
3202 /* When stopping units, warn if they can still be triggered by
3203 * another active unit (socket, path, timer) */
3204 if (!arg_quiet
&& streq(method
, "StopUnit"))
3205 STRV_FOREACH(name
, names
)
3206 check_triggering_units(bus
, *name
);
3209 if (r
>= 0 && arg_wait
) {
3211 q
= sd_event_loop(wait_context
.event
);
3213 return log_error_errno(q
, "Failed to run event loop: %m");
3214 if (wait_context
.any_failed
)
3222 static int logind_set_wall_message(void) {
3223 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3225 _cleanup_free_
char *m
= NULL
;
3228 r
= acquire_bus(BUS_FULL
, &bus
);
3232 m
= strv_join(arg_wall
, " ");
3236 r
= sd_bus_call_method(
3238 "org.freedesktop.login1",
3239 "/org/freedesktop/login1",
3240 "org.freedesktop.login1.Manager",
3249 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
3254 /* Ask systemd-logind, which might grant access to unprivileged users
3255 * through PolicyKit */
3256 static int logind_reboot(enum action a
) {
3258 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3259 const char *method
, *description
;
3263 r
= acquire_bus(BUS_FULL
, &bus
);
3269 case ACTION_POWEROFF
:
3270 method
= "PowerOff";
3271 description
= "power off system";
3276 description
= "reboot system";
3281 description
= "halt system";
3284 case ACTION_SUSPEND
:
3286 description
= "suspend system";
3289 case ACTION_HIBERNATE
:
3290 method
= "Hibernate";
3291 description
= "hibernate system";
3294 case ACTION_HYBRID_SLEEP
:
3295 method
= "HybridSleep";
3296 description
= "put system into hybrid sleep";
3303 polkit_agent_open_maybe();
3304 (void) logind_set_wall_message();
3306 r
= sd_bus_call_method(
3308 "org.freedesktop.login1",
3309 "/org/freedesktop/login1",
3310 "org.freedesktop.login1.Manager",
3314 "b", arg_ask_password
);
3316 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
3324 static int logind_check_inhibitors(enum action a
) {
3326 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3327 _cleanup_strv_free_
char **sessions
= NULL
;
3328 const char *what
, *who
, *why
, *mode
;
3335 if (arg_ignore_inhibitors
|| arg_force
> 0)
3347 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
3350 r
= acquire_bus(BUS_FULL
, &bus
);
3354 r
= sd_bus_call_method(
3356 "org.freedesktop.login1",
3357 "/org/freedesktop/login1",
3358 "org.freedesktop.login1.Manager",
3364 /* If logind is not around, then there are no inhibitors... */
3367 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3369 return bus_log_parse_error(r
);
3371 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3372 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3373 _cleanup_strv_free_
char **sv
= NULL
;
3375 if (!streq(mode
, "block"))
3378 sv
= strv_split(what
, ":");
3382 if (!pid_is_valid((pid_t
) pid
)) {
3383 log_error("Invalid PID "PID_FMT
".", (pid_t
) pid
);
3387 if (!strv_contains(sv
,
3392 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3395 get_process_comm(pid
, &comm
);
3396 user
= uid_to_name(uid
);
3398 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3399 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3404 return bus_log_parse_error(r
);
3406 r
= sd_bus_message_exit_container(reply
);
3408 return bus_log_parse_error(r
);
3410 /* Check for current sessions */
3411 sd_get_sessions(&sessions
);
3412 STRV_FOREACH(s
, sessions
) {
3413 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3415 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3418 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3421 if (sd_session_get_type(*s
, &type
) < 0 || !STR_IN_SET(type
, "x11", "wayland", "tty", "mir"))
3424 sd_session_get_tty(*s
, &tty
);
3425 sd_session_get_seat(*s
, &seat
);
3426 sd_session_get_service(*s
, &service
);
3427 user
= uid_to_name(uid
);
3429 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3436 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3437 action_table
[a
].verb
);
3445 static int logind_prepare_firmware_setup(void) {
3447 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3451 r
= acquire_bus(BUS_FULL
, &bus
);
3455 r
= sd_bus_call_method(
3457 "org.freedesktop.login1",
3458 "/org/freedesktop/login1",
3459 "org.freedesktop.login1.Manager",
3460 "SetRebootToFirmwareSetup",
3465 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3469 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3474 static int prepare_firmware_setup(void) {
3477 if (!arg_firmware_setup
)
3480 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3482 r
= efi_set_reboot_to_firmware(true);
3484 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3489 return logind_prepare_firmware_setup();
3492 static int set_exit_code(uint8_t code
) {
3493 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3497 r
= acquire_bus(BUS_MANAGER
, &bus
);
3501 r
= sd_bus_call_method(
3503 "org.freedesktop.systemd1",
3504 "/org/freedesktop/systemd1",
3505 "org.freedesktop.systemd1.Manager",
3511 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3516 static int start_special(int argc
, char *argv
[], void *userdata
) {
3519 bool termination_action
; /* an action that terminates the manager,
3520 * can be performed also by signal. */
3524 a
= verb_to_action(argv
[0]);
3526 r
= logind_check_inhibitors(a
);
3530 if (arg_force
>= 2 && geteuid() != 0) {
3531 log_error("Must be root.");
3535 r
= prepare_firmware_setup();
3539 if (a
== ACTION_REBOOT
&& argc
> 1) {
3540 r
= update_reboot_parameter_and_warn(argv
[1]);
3544 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3547 /* If the exit code is not given on the command line,
3548 * don't reset it to zero: just keep it as it might
3549 * have been set previously. */
3551 r
= safe_atou8(argv
[1], &code
);
3553 return log_error_errno(r
, "Invalid exit code.");
3555 r
= set_exit_code(code
);
3560 termination_action
= IN_SET(a
,
3564 if (termination_action
&& arg_force
>= 2)
3567 if (arg_force
>= 1 &&
3568 (termination_action
|| IN_SET(a
, ACTION_KEXEC
, ACTION_EXIT
)))
3569 r
= trivial_method(argc
, argv
, userdata
);
3571 /* First try logind, to allow authentication with polkit */
3578 ACTION_HYBRID_SLEEP
)) {
3580 r
= logind_reboot(a
);
3583 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3584 /* requested operation is not supported or already in progress */
3587 /* On all other errors, try low-level operation. In order to minimize the difference between
3588 * operation with and without logind, we explicitly enable non-blocking mode for this, as
3589 * logind's shutdown operations are always non-blocking. */
3591 arg_no_block
= true;
3593 } else if (IN_SET(a
, ACTION_EXIT
, ACTION_KEXEC
))
3594 /* Since exit/kexec are so close in behaviour to power-off/reboot, let's also make them
3595 * asynchronous, in order to not confuse the user needlessly with unexpected behaviour. */
3596 arg_no_block
= true;
3598 r
= start_unit(argc
, argv
, userdata
);
3601 if (termination_action
&& arg_force
< 2 &&
3602 IN_SET(r
, -ENOENT
, -ETIMEDOUT
))
3603 log_notice("It is possible to perform action directly, see discussion of --force --force in man:systemctl(1).");
3608 static int start_system_special(int argc
, char *argv
[], void *userdata
) {
3609 /* Like start_special above, but raises an error when running in user mode */
3611 if (arg_scope
!= UNIT_FILE_SYSTEM
) {
3612 log_error("Bad action for %s mode.",
3613 arg_scope
== UNIT_FILE_GLOBAL
? "--global" : "--user");
3617 return start_special(argc
, argv
, userdata
);
3620 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3621 _cleanup_strv_free_
char **names
= NULL
;
3622 UnitActiveState active_state
;
3628 r
= acquire_bus(BUS_MANAGER
, &bus
);
3632 r
= expand_names(bus
, args
, NULL
, &names
);
3634 return log_error_errno(r
, "Failed to expand names: %m");
3636 STRV_FOREACH(name
, names
) {
3637 r
= get_state_one_unit(bus
, *name
, &active_state
);
3642 puts(unit_active_state_to_string(active_state
));
3644 for (i
= 0; i
< nb_states
; ++i
)
3645 if (good_states
[i
] == active_state
)
3649 /* use the given return code for the case that we won't find
3650 * any unit which matches the list */
3651 return found
? 0 : code
;
3654 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3655 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3656 /* According to LSB: 3, "program is not running" */
3657 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3660 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3661 const UnitActiveState states
[] = { UNIT_FAILED
};
3662 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3665 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3666 _cleanup_strv_free_
char **names
= NULL
;
3667 char *kill_who
= NULL
, **name
;
3671 r
= acquire_bus(BUS_MANAGER
, &bus
);
3675 polkit_agent_open_maybe();
3678 arg_kill_who
= "all";
3680 /* --fail was specified */
3681 if (streq(arg_job_mode
, "fail"))
3682 kill_who
= strjoina(arg_kill_who
, "-fail");
3684 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3686 return log_error_errno(r
, "Failed to expand names: %m");
3688 STRV_FOREACH(name
, names
) {
3689 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3691 q
= sd_bus_call_method(
3693 "org.freedesktop.systemd1",
3694 "/org/freedesktop/systemd1",
3695 "org.freedesktop.systemd1.Manager",
3699 "ssi", *name
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3701 log_error_errno(q
, "Failed to kill unit %s: %s", *name
, bus_error_message(&error
, q
));
3710 typedef struct ExecStatusInfo
{
3718 usec_t start_timestamp
;
3719 usec_t exit_timestamp
;
3724 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3727 static void exec_status_info_free(ExecStatusInfo
*i
) {
3736 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3737 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3740 int32_t code
, status
;
3746 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3748 return bus_log_parse_error(r
);
3752 r
= sd_bus_message_read(m
, "s", &path
);
3754 return bus_log_parse_error(r
);
3756 i
->path
= strdup(path
);
3760 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3762 return bus_log_parse_error(r
);
3764 r
= sd_bus_message_read(m
,
3767 &start_timestamp
, &start_timestamp_monotonic
,
3768 &exit_timestamp
, &exit_timestamp_monotonic
,
3772 return bus_log_parse_error(r
);
3775 i
->start_timestamp
= (usec_t
) start_timestamp
;
3776 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3777 i
->pid
= (pid_t
) pid
;
3781 r
= sd_bus_message_exit_container(m
);
3783 return bus_log_parse_error(r
);
3788 typedef struct UnitCondition
{
3795 LIST_FIELDS(struct UnitCondition
, conditions
);
3798 static void unit_condition_free(UnitCondition
*c
) {
3807 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition
*, unit_condition_free
);
3809 typedef struct UnitStatusInfo
{
3811 const char *load_state
;
3812 const char *active_state
;
3813 const char *sub_state
;
3814 const char *unit_file_state
;
3815 const char *unit_file_preset
;
3817 const char *description
;
3818 const char *following
;
3820 char **documentation
;
3822 const char *fragment_path
;
3823 const char *source_path
;
3824 const char *control_group
;
3826 char **dropin_paths
;
3828 const char *load_error
;
3831 usec_t inactive_exit_timestamp
;
3832 usec_t inactive_exit_timestamp_monotonic
;
3833 usec_t active_enter_timestamp
;
3834 usec_t active_exit_timestamp
;
3835 usec_t inactive_enter_timestamp
;
3837 bool need_daemon_reload
;
3843 const char *status_text
;
3844 const char *pid_file
;
3848 usec_t start_timestamp
;
3849 usec_t exit_timestamp
;
3851 int exit_code
, exit_status
;
3853 usec_t condition_timestamp
;
3854 bool condition_result
;
3855 LIST_HEAD(UnitCondition
, conditions
);
3857 usec_t assert_timestamp
;
3859 bool failed_assert_trigger
;
3860 bool failed_assert_negate
;
3861 const char *failed_assert
;
3862 const char *failed_assert_parameter
;
3863 usec_t next_elapse_real
;
3864 usec_t next_elapse_monotonic
;
3867 unsigned n_accepted
;
3868 unsigned n_connections
;
3871 /* Pairs of type, path */
3875 const char *sysfs_path
;
3877 /* Mount, Automount */
3884 uint64_t memory_current
;
3885 uint64_t memory_low
;
3886 uint64_t memory_high
;
3887 uint64_t memory_max
;
3888 uint64_t memory_swap_max
;
3889 uint64_t memory_limit
;
3890 uint64_t cpu_usage_nsec
;
3891 uint64_t tasks_current
;
3894 uint64_t ip_ingress_bytes
;
3895 uint64_t ip_egress_bytes
;
3897 LIST_HEAD(ExecStatusInfo
, exec
);
3900 static void unit_status_info_free(UnitStatusInfo
*info
) {
3904 strv_free(info
->documentation
);
3905 strv_free(info
->dropin_paths
);
3906 strv_free(info
->listen
);
3908 while ((c
= info
->conditions
)) {
3909 LIST_REMOVE(conditions
, info
->conditions
, c
);
3910 unit_condition_free(c
);
3913 while ((p
= info
->exec
)) {
3914 LIST_REMOVE(exec
, info
->exec
, p
);
3915 exec_status_info_free(p
);
3919 static void print_status_info(
3925 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3927 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3928 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3935 /* This shows pretty information about a unit. See
3936 * print_property() for a low-level property printer */
3938 if (streq_ptr(i
->active_state
, "failed")) {
3939 active_on
= ansi_highlight_red();
3940 active_off
= ansi_normal();
3941 } else if (STRPTR_IN_SET(i
->active_state
, "active", "reloading")) {
3942 active_on
= ansi_highlight_green();
3943 active_off
= ansi_normal();
3945 active_on
= active_off
= "";
3947 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3949 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3950 printf(" - %s", i
->description
);
3955 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3957 if (streq_ptr(i
->load_state
, "error")) {
3958 on
= ansi_highlight_red();
3959 off
= ansi_normal();
3963 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3965 if (i
->load_error
!= 0)
3966 printf(" Loaded: %s%s%s (Reason: %s)\n",
3967 on
, strna(i
->load_state
), off
, i
->load_error
);
3968 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3969 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3970 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3971 else if (path
&& !isempty(i
->unit_file_state
))
3972 printf(" Loaded: %s%s%s (%s; %s)\n",
3973 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3975 printf(" Loaded: %s%s%s (%s)\n",
3976 on
, strna(i
->load_state
), off
, path
);
3978 printf(" Loaded: %s%s%s\n",
3979 on
, strna(i
->load_state
), off
);
3982 printf("Transient: yes\n");
3984 if (!strv_isempty(i
->dropin_paths
)) {
3985 _cleanup_free_
char *dir
= NULL
;
3989 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3990 if (! dir
|| last
) {
3991 printf(dir
? " " : " Drop-In: ");
3995 dir
= dirname_malloc(*dropin
);
4001 printf("%s\n %s", dir
,
4002 special_glyph(TREE_RIGHT
));
4005 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
4007 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
4011 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
4013 printf(" Active: %s%s (%s)%s",
4014 active_on
, strna(i
->active_state
), ss
, active_off
);
4016 printf(" Active: %s%s%s",
4017 active_on
, strna(i
->active_state
), active_off
);
4019 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
4020 printf(" (Result: %s)", i
->result
);
4022 timestamp
= STRPTR_IN_SET(i
->active_state
, "active", "reloading") ? i
->active_enter_timestamp
:
4023 STRPTR_IN_SET(i
->active_state
, "inactive", "failed") ? i
->inactive_enter_timestamp
:
4024 STRPTR_IN_SET(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
4025 i
->active_exit_timestamp
;
4027 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
4028 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
4031 printf(" since %s; %s\n", s2
, s1
);
4033 printf(" since %s\n", s2
);
4037 if (endswith(i
->id
, ".timer")) {
4038 char tstamp1
[FORMAT_TIMESTAMP_RELATIVE_MAX
],
4039 tstamp2
[FORMAT_TIMESTAMP_MAX
];
4040 char *next_rel_time
, *next_time
;
4041 dual_timestamp nw
, next
= {i
->next_elapse_real
,
4042 i
->next_elapse_monotonic
};
4045 printf(" Trigger: ");
4047 dual_timestamp_get(&nw
);
4048 next_elapse
= calc_next_elapse(&nw
, &next
);
4049 next_rel_time
= format_timestamp_relative(tstamp1
,
4052 next_time
= format_timestamp(tstamp2
,
4056 if (next_time
&& next_rel_time
)
4057 printf("%s; %s\n", next_time
, next_rel_time
);
4062 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
4066 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
4067 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
4069 printf("Condition: start %scondition failed%s at %s%s%s\n",
4070 ansi_highlight_yellow(), ansi_normal(),
4071 s2
, s1
? "; " : "", strempty(s1
));
4073 LIST_FOREACH(conditions
, c
, i
->conditions
)
4074 if (c
->tristate
< 0)
4077 LIST_FOREACH(conditions
, c
, i
->conditions
)
4078 if (c
->tristate
< 0)
4079 printf(" %s %s=%s%s%s was not met\n",
4080 --n
? special_glyph(TREE_BRANCH
) : special_glyph(TREE_RIGHT
),
4082 c
->trigger
? "|" : "",
4083 c
->negate
? "!" : "",
4087 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
4088 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
4089 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
4091 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
4092 ansi_highlight_red(), ansi_normal(),
4093 s2
, s1
? "; " : "", strempty(s1
));
4094 if (i
->failed_assert_trigger
)
4095 printf(" none of the trigger assertions were met\n");
4096 else if (i
->failed_assert
)
4097 printf(" %s=%s%s was not met\n",
4099 i
->failed_assert_negate
? "!" : "",
4100 i
->failed_assert_parameter
);
4104 printf(" Device: %s\n", i
->sysfs_path
);
4106 printf(" Where: %s\n", i
->where
);
4108 printf(" What: %s\n", i
->what
);
4110 STRV_FOREACH(t
, i
->documentation
)
4111 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
4113 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
4114 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
4117 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
4119 LIST_FOREACH(exec
, p
, i
->exec
) {
4120 _cleanup_free_
char *argv
= NULL
;
4123 /* Only show exited processes here */
4127 argv
= strv_join(p
->argv
, " ");
4128 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
4130 good
= is_clean_exit(p
->code
, p
->status
, EXIT_CLEAN_DAEMON
, NULL
);
4132 on
= ansi_highlight_red();
4133 off
= ansi_normal();
4137 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
4139 if (p
->code
== CLD_EXITED
) {
4142 printf("status=%i", p
->status
);
4144 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
4149 printf("signal=%s", signal_to_string(p
->status
));
4151 printf(")%s\n", off
);
4153 if (i
->main_pid
== p
->pid
&&
4154 i
->start_timestamp
== p
->start_timestamp
&&
4155 i
->exit_timestamp
== p
->start_timestamp
)
4156 /* Let's not show this twice */
4159 if (p
->pid
== i
->control_pid
)
4163 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
4164 if (i
->main_pid
> 0) {
4165 printf(" Main PID: "PID_FMT
, i
->main_pid
);
4168 _cleanup_free_
char *comm
= NULL
;
4169 (void) get_process_comm(i
->main_pid
, &comm
);
4171 printf(" (%s)", comm
);
4172 } else if (i
->exit_code
> 0) {
4173 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
4175 if (i
->exit_code
== CLD_EXITED
) {
4178 printf("status=%i", i
->exit_status
);
4180 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
4185 printf("signal=%s", signal_to_string(i
->exit_status
));
4190 if (i
->control_pid
> 0) {
4191 _cleanup_free_
char *c
= NULL
;
4193 if (i
->main_pid
> 0)
4194 fputs("; Control PID: ", stdout
);
4196 fputs("Cntrl PID: ", stdout
); /* if first in column, abbreviated so it fits alignment */
4198 printf(PID_FMT
, i
->control_pid
);
4200 (void) get_process_comm(i
->control_pid
, &c
);
4209 printf(" Status: \"%s\"\n", i
->status_text
);
4210 if (i
->status_errno
> 0)
4211 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
4213 if (i
->ip_ingress_bytes
!= (uint64_t) -1 && i
->ip_egress_bytes
!= (uint64_t) -1) {
4214 char buf_in
[FORMAT_BYTES_MAX
], buf_out
[FORMAT_BYTES_MAX
];
4216 printf(" IP: %s in, %s out\n",
4217 format_bytes(buf_in
, sizeof(buf_in
), i
->ip_ingress_bytes
),
4218 format_bytes(buf_out
, sizeof(buf_out
), i
->ip_egress_bytes
));
4221 if (i
->tasks_current
!= (uint64_t) -1) {
4222 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
4224 if (i
->tasks_max
!= (uint64_t) -1)
4225 printf(" (limit: %" PRIu64
")\n", i
->tasks_max
);
4230 if (i
->memory_current
!= (uint64_t) -1) {
4231 char buf
[FORMAT_BYTES_MAX
];
4233 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
4235 if (i
->memory_low
> 0 || i
->memory_high
!= CGROUP_LIMIT_MAX
||
4236 i
->memory_max
!= CGROUP_LIMIT_MAX
|| i
->memory_swap_max
!= CGROUP_LIMIT_MAX
||
4237 i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4238 const char *prefix
= "";
4241 if (i
->memory_low
> 0) {
4242 printf("%slow: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_low
));
4245 if (i
->memory_high
!= CGROUP_LIMIT_MAX
) {
4246 printf("%shigh: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_high
));
4249 if (i
->memory_max
!= CGROUP_LIMIT_MAX
) {
4250 printf("%smax: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_max
));
4253 if (i
->memory_swap_max
!= CGROUP_LIMIT_MAX
) {
4254 printf("%sswap max: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_swap_max
));
4257 if (i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4258 printf("%slimit: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
4266 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
4267 char buf
[FORMAT_TIMESPAN_MAX
];
4268 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
4271 if (i
->control_group
) {
4272 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4273 static const char prefix
[] = " ";
4276 printf(" CGroup: %s\n", i
->control_group
);
4279 if (c
> sizeof(prefix
) - 1)
4280 c
-= sizeof(prefix
) - 1;
4284 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
4289 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4291 if (i
->main_pid
> 0)
4292 extra
[k
++] = i
->main_pid
;
4294 if (i
->control_pid
> 0)
4295 extra
[k
++] = i
->control_pid
;
4297 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
4299 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
4302 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
4303 show_journal_by_unit(
4308 i
->inactive_exit_timestamp_monotonic
,
4311 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
4312 SD_JOURNAL_LOCAL_ONLY
,
4313 arg_scope
== UNIT_FILE_SYSTEM
,
4316 if (i
->need_daemon_reload
)
4317 warn_unit_file_changed(i
->id
);
4320 static void show_unit_help(UnitStatusInfo
*i
) {
4325 if (!i
->documentation
) {
4326 log_info("Documentation for %s not known.", i
->id
);
4330 STRV_FOREACH(p
, i
->documentation
)
4331 if (startswith(*p
, "man:"))
4332 show_man_page(*p
+ 4, false);
4334 log_info("Can't show: %s", *p
);
4337 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
4344 switch (contents
[0]) {
4346 case SD_BUS_TYPE_STRING
: {
4349 r
= sd_bus_message_read(m
, "s", &s
);
4351 return bus_log_parse_error(r
);
4354 if (streq(name
, "Id"))
4356 else if (streq(name
, "LoadState"))
4358 else if (streq(name
, "ActiveState"))
4359 i
->active_state
= s
;
4360 else if (streq(name
, "SubState"))
4362 else if (streq(name
, "Description"))
4364 else if (streq(name
, "FragmentPath"))
4365 i
->fragment_path
= s
;
4366 else if (streq(name
, "SourcePath"))
4369 else if (streq(name
, "DefaultControlGroup")) {
4371 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
4373 i
->control_group
= e
;
4376 else if (streq(name
, "ControlGroup"))
4377 i
->control_group
= s
;
4378 else if (streq(name
, "StatusText"))
4380 else if (streq(name
, "PIDFile"))
4382 else if (streq(name
, "SysFSPath"))
4384 else if (streq(name
, "Where"))
4386 else if (streq(name
, "What"))
4388 else if (streq(name
, "Following"))
4390 else if (streq(name
, "UnitFileState"))
4391 i
->unit_file_state
= s
;
4392 else if (streq(name
, "UnitFilePreset"))
4393 i
->unit_file_preset
= s
;
4394 else if (streq(name
, "Result"))
4401 case SD_BUS_TYPE_BOOLEAN
: {
4404 r
= sd_bus_message_read(m
, "b", &b
);
4406 return bus_log_parse_error(r
);
4408 if (streq(name
, "Accept"))
4410 else if (streq(name
, "NeedDaemonReload"))
4411 i
->need_daemon_reload
= b
;
4412 else if (streq(name
, "ConditionResult"))
4413 i
->condition_result
= b
;
4414 else if (streq(name
, "AssertResult"))
4415 i
->assert_result
= b
;
4416 else if (streq(name
, "Transient"))
4422 case SD_BUS_TYPE_UINT32
: {
4425 r
= sd_bus_message_read(m
, "u", &u
);
4427 return bus_log_parse_error(r
);
4429 if (streq(name
, "MainPID")) {
4431 i
->main_pid
= (pid_t
) u
;
4434 } else if (streq(name
, "ControlPID"))
4435 i
->control_pid
= (pid_t
) u
;
4436 else if (streq(name
, "ExecMainPID")) {
4438 i
->main_pid
= (pid_t
) u
;
4439 } else if (streq(name
, "NAccepted"))
4441 else if (streq(name
, "NConnections"))
4442 i
->n_connections
= u
;
4447 case SD_BUS_TYPE_INT32
: {
4450 r
= sd_bus_message_read(m
, "i", &j
);
4452 return bus_log_parse_error(r
);
4454 if (streq(name
, "ExecMainCode"))
4455 i
->exit_code
= (int) j
;
4456 else if (streq(name
, "ExecMainStatus"))
4457 i
->exit_status
= (int) j
;
4458 else if (streq(name
, "StatusErrno"))
4459 i
->status_errno
= (int) j
;
4464 case SD_BUS_TYPE_UINT64
: {
4467 r
= sd_bus_message_read(m
, "t", &u
);
4469 return bus_log_parse_error(r
);
4471 if (streq(name
, "ExecMainStartTimestamp"))
4472 i
->start_timestamp
= (usec_t
) u
;
4473 else if (streq(name
, "ExecMainExitTimestamp"))
4474 i
->exit_timestamp
= (usec_t
) u
;
4475 else if (streq(name
, "ActiveEnterTimestamp"))
4476 i
->active_enter_timestamp
= (usec_t
) u
;
4477 else if (streq(name
, "InactiveEnterTimestamp"))
4478 i
->inactive_enter_timestamp
= (usec_t
) u
;
4479 else if (streq(name
, "InactiveExitTimestamp"))
4480 i
->inactive_exit_timestamp
= (usec_t
) u
;
4481 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4482 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4483 else if (streq(name
, "ActiveExitTimestamp"))
4484 i
->active_exit_timestamp
= (usec_t
) u
;
4485 else if (streq(name
, "ConditionTimestamp"))
4486 i
->condition_timestamp
= (usec_t
) u
;
4487 else if (streq(name
, "AssertTimestamp"))
4488 i
->assert_timestamp
= (usec_t
) u
;
4489 else if (streq(name
, "MemoryCurrent"))
4490 i
->memory_current
= u
;
4491 else if (streq(name
, "MemoryLow"))
4493 else if (streq(name
, "MemoryHigh"))
4495 else if (streq(name
, "MemoryMax"))
4497 else if (streq(name
, "MemorySwapMax"))
4498 i
->memory_swap_max
= u
;
4499 else if (streq(name
, "MemoryLimit"))
4500 i
->memory_limit
= u
;
4501 else if (streq(name
, "TasksCurrent"))
4502 i
->tasks_current
= u
;
4503 else if (streq(name
, "TasksMax"))
4505 else if (streq(name
, "CPUUsageNSec"))
4506 i
->cpu_usage_nsec
= u
;
4507 else if (streq(name
, "NextElapseUSecMonotonic"))
4508 i
->next_elapse_monotonic
= u
;
4509 else if (streq(name
, "NextElapseUSecRealtime"))
4510 i
->next_elapse_real
= u
;
4511 else if (streq(name
, "IPIngressBytes"))
4512 i
->ip_ingress_bytes
= u
;
4513 else if (streq(name
, "IPEgressBytes"))
4514 i
->ip_egress_bytes
= u
;
4519 case SD_BUS_TYPE_ARRAY
:
4521 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4522 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4524 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4526 return bus_log_parse_error(r
);
4528 info
= new0(ExecStatusInfo
, 1);
4532 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4534 info
->name
= strdup(name
);
4538 LIST_PREPEND(exec
, i
->exec
, info
);
4540 info
= new0(ExecStatusInfo
, 1);
4546 return bus_log_parse_error(r
);
4548 r
= sd_bus_message_exit_container(m
);
4550 return bus_log_parse_error(r
);
4554 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4555 const char *type
, *path
;
4557 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4559 return bus_log_parse_error(r
);
4561 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4563 r
= strv_extend(&i
->listen
, type
);
4567 r
= strv_extend(&i
->listen
, path
);
4572 return bus_log_parse_error(r
);
4574 r
= sd_bus_message_exit_container(m
);
4576 return bus_log_parse_error(r
);
4580 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4582 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4584 return bus_log_parse_error(r
);
4586 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4588 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4590 return bus_log_parse_error(r
);
4592 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4593 const char *cond
, *param
;
4594 int trigger
, negate
;
4597 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4599 return bus_log_parse_error(r
);
4601 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4602 _cleanup_(unit_condition_freep
) UnitCondition
*c
= NULL
;
4604 log_debug("%s trigger=%d negate=%d %s →%d", cond
, trigger
, negate
, param
, state
);
4606 c
= new0(UnitCondition
, 1);
4610 c
->name
= strdup(cond
);
4611 c
->param
= strdup(param
);
4612 if (!c
->name
|| !c
->param
)
4615 c
->trigger
= trigger
;
4617 c
->tristate
= state
;
4619 LIST_PREPEND(conditions
, i
->conditions
, c
);
4623 return bus_log_parse_error(r
);
4625 r
= sd_bus_message_exit_container(m
);
4627 return bus_log_parse_error(r
);
4629 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4630 const char *cond
, *param
;
4631 int trigger
, negate
;
4634 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4636 return bus_log_parse_error(r
);
4638 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4639 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4640 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4641 i
->failed_assert
= cond
;
4642 i
->failed_assert_trigger
= trigger
;
4643 i
->failed_assert_negate
= negate
;
4644 i
->failed_assert_parameter
= param
;
4648 return bus_log_parse_error(r
);
4650 r
= sd_bus_message_exit_container(m
);
4652 return bus_log_parse_error(r
);
4659 case SD_BUS_TYPE_STRUCT_BEGIN
:
4661 if (streq(name
, "LoadError")) {
4662 const char *n
, *message
;
4664 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4666 return bus_log_parse_error(r
);
4668 if (!isempty(message
))
4669 i
->load_error
= message
;
4682 r
= sd_bus_message_skip(m
, contents
);
4684 return bus_log_parse_error(r
);
4689 #define print_prop(name, fmt, ...) \
4692 printf(fmt "\n", __VA_ARGS__); \
4694 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4697 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4703 /* This is a low-level property printer, see
4704 * print_status_info() for the nicer output */
4706 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4707 /* skip what we didn't read */
4708 r
= sd_bus_message_skip(m
, contents
);
4712 switch (contents
[0]) {
4714 case SD_BUS_TYPE_STRUCT_BEGIN
:
4716 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4719 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4721 return bus_log_parse_error(r
);
4724 print_prop(name
, "%"PRIu32
, u
);
4726 print_prop(name
, "%s", "");
4730 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4733 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4735 return bus_log_parse_error(r
);
4737 if (arg_all
|| !isempty(s
))
4738 print_prop(name
, "%s", s
);
4742 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4743 const char *a
= NULL
, *b
= NULL
;
4745 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4747 return bus_log_parse_error(r
);
4749 if (arg_all
|| !isempty(a
) || !isempty(b
))
4750 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4753 } else if (streq_ptr(name
, "SystemCallFilter")) {
4754 _cleanup_strv_free_
char **l
= NULL
;
4757 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4759 return bus_log_parse_error(r
);
4761 r
= sd_bus_message_read(m
, "b", &whitelist
);
4763 return bus_log_parse_error(r
);
4765 r
= sd_bus_message_read_strv(m
, &l
);
4767 return bus_log_parse_error(r
);
4769 r
= sd_bus_message_exit_container(m
);
4771 return bus_log_parse_error(r
);
4773 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4778 fputs(name
, stdout
);
4785 STRV_FOREACH(i
, l
) {
4793 fputc('\n', stdout
);
4801 case SD_BUS_TYPE_ARRAY
:
4803 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4807 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4809 return bus_log_parse_error(r
);
4811 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4812 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path
, yes_no(ignore
));
4815 return bus_log_parse_error(r
);
4817 r
= sd_bus_message_exit_container(m
);
4819 return bus_log_parse_error(r
);
4823 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4824 const char *type
, *path
;
4826 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4828 return bus_log_parse_error(r
);
4830 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4831 print_prop(type
, "%s", path
);
4833 return bus_log_parse_error(r
);
4835 r
= sd_bus_message_exit_container(m
);
4837 return bus_log_parse_error(r
);
4841 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4842 const char *type
, *path
;
4844 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4846 return bus_log_parse_error(r
);
4848 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4852 printf("Listen%s=%s\n", type
, path
);
4854 return bus_log_parse_error(r
);
4856 r
= sd_bus_message_exit_container(m
);
4858 return bus_log_parse_error(r
);
4862 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4864 uint64_t value
, next_elapse
;
4866 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4868 return bus_log_parse_error(r
);
4870 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4871 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4873 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4874 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4875 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4878 return bus_log_parse_error(r
);
4880 r
= sd_bus_message_exit_container(m
);
4882 return bus_log_parse_error(r
);
4886 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4887 ExecStatusInfo info
= {};
4889 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4891 return bus_log_parse_error(r
);
4893 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4894 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4895 _cleanup_free_
char *tt
;
4897 tt
= strv_join(info
.argv
, " ");
4900 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4903 yes_no(info
.ignore
),
4904 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4905 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4907 sigchld_code_to_string(info
.code
),
4909 info
.code
== CLD_EXITED
? "" : "/",
4910 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4913 strv_free(info
.argv
);
4917 r
= sd_bus_message_exit_container(m
);
4919 return bus_log_parse_error(r
);
4923 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4924 const char *path
, *rwm
;
4926 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4928 return bus_log_parse_error(r
);
4930 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4931 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4933 return bus_log_parse_error(r
);
4935 r
= sd_bus_message_exit_container(m
);
4937 return bus_log_parse_error(r
);
4941 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4942 STR_IN_SET(name
, "IODeviceWeight", "BlockIODeviceWeight")) {
4946 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4948 return bus_log_parse_error(r
);
4950 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4951 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4953 return bus_log_parse_error(r
);
4955 r
= sd_bus_message_exit_container(m
);
4957 return bus_log_parse_error(r
);
4961 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4962 (cgroup_io_limit_type_from_string(name
) >= 0 ||
4963 STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
4967 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4969 return bus_log_parse_error(r
);
4971 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4972 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4974 return bus_log_parse_error(r
);
4976 r
= sd_bus_message_exit_container(m
);
4978 return bus_log_parse_error(r
);
4986 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4988 return bus_log_parse_error(r
);
4991 r
= sd_bus_message_skip(m
, contents
);
4993 return bus_log_parse_error(r
);
4996 printf("%s=[unprintable]\n", name
);
5002 static int show_one(
5007 bool show_properties
,
5011 static const struct bus_properties_map property_map
[] = {
5012 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
5013 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
) },
5017 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5018 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5019 _cleanup_set_free_ Set
*found_properties
= NULL
;
5020 _cleanup_(unit_status_info_free
) UnitStatusInfo info
= {
5021 .memory_current
= (uint64_t) -1,
5022 .memory_high
= CGROUP_LIMIT_MAX
,
5023 .memory_max
= CGROUP_LIMIT_MAX
,
5024 .memory_swap_max
= CGROUP_LIMIT_MAX
,
5025 .memory_limit
= (uint64_t) -1,
5026 .cpu_usage_nsec
= (uint64_t) -1,
5027 .tasks_current
= (uint64_t) -1,
5028 .tasks_max
= (uint64_t) -1,
5029 .ip_ingress_bytes
= (uint64_t) -1,
5030 .ip_egress_bytes
= (uint64_t) -1,
5037 log_debug("Showing one %s", path
);
5039 r
= sd_bus_call_method(
5041 "org.freedesktop.systemd1",
5043 "org.freedesktop.DBus.Properties",
5049 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
5052 r
= bus_message_map_all_properties(reply
, property_map
, &error
, &info
);
5054 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
5056 if (streq_ptr(info
.load_state
, "not-found") && streq_ptr(info
.active_state
, "inactive")) {
5057 log_full(streq(verb
, "status") ? LOG_ERR
: LOG_DEBUG
,
5058 "Unit %s could not be found.", unit
);
5060 if (streq(verb
, "status"))
5061 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
;
5063 if (!streq(verb
, "show"))
5067 r
= sd_bus_message_rewind(reply
, true);
5069 return log_error_errno(r
, "Failed to rewind: %s", bus_error_message(&error
, r
));
5072 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
5074 return bus_log_parse_error(r
);
5081 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
5082 const char *name
, *contents
;
5084 r
= sd_bus_message_read(reply
, "s", &name
);
5086 return bus_log_parse_error(r
);
5088 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
5090 return bus_log_parse_error(r
);
5092 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
5094 return bus_log_parse_error(r
);
5096 if (show_properties
) {
5097 r
= set_ensure_allocated(&found_properties
, &string_hash_ops
);
5101 r
= set_put(found_properties
, name
);
5102 if (r
< 0 && r
!= EEXIST
)
5105 r
= print_property(name
, reply
, contents
);
5107 r
= status_property(name
, reply
, &info
, contents
);
5111 r
= sd_bus_message_exit_container(reply
);
5113 return bus_log_parse_error(r
);
5115 r
= sd_bus_message_exit_container(reply
);
5117 return bus_log_parse_error(r
);
5120 return bus_log_parse_error(r
);
5122 r
= sd_bus_message_exit_container(reply
);
5124 return bus_log_parse_error(r
);
5127 if (show_properties
) {
5130 STRV_FOREACH(pp
, arg_properties
)
5131 if (!set_contains(found_properties
, *pp
))
5132 log_debug("Property %s does not exist.", *pp
);
5134 } else if (streq(verb
, "help"))
5135 show_unit_help(&info
);
5136 else if (streq(verb
, "status")) {
5137 print_status_info(bus
, &info
, ellipsized
);
5139 if (info
.active_state
&& !STR_IN_SET(info
.active_state
, "active", "reloading"))
5140 r
= EXIT_PROGRAM_NOT_RUNNING
;
5142 r
= EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
;
5148 static int get_unit_dbus_path_by_pid(
5153 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5154 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5158 r
= sd_bus_call_method(
5160 "org.freedesktop.systemd1",
5161 "/org/freedesktop/systemd1",
5162 "org.freedesktop.systemd1.Manager",
5168 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
5170 r
= sd_bus_message_read(reply
, "o", &u
);
5172 return bus_log_parse_error(r
);
5182 static int show_all(
5185 bool show_properties
,
5189 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5190 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
5195 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
5199 pager_open(arg_no_pager
, false);
5203 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
5205 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
5206 _cleanup_free_
char *p
= NULL
;
5208 p
= unit_dbus_path_from_name(u
->id
);
5212 r
= show_one(verb
, bus
, p
, u
->id
, show_properties
, new_line
, ellipsized
);
5215 else if (r
> 0 && ret
== 0)
5222 static int show_system_status(sd_bus
*bus
) {
5223 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
5224 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5225 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
5226 _cleanup_free_
char *hn
= NULL
;
5227 const char *on
, *off
;
5230 hn
= gethostname_malloc();
5234 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &error
, &mi
);
5236 return log_error_errno(r
, "Failed to read server status: %s", bus_error_message(&error
, r
));
5238 if (streq_ptr(mi
.state
, "degraded")) {
5239 on
= ansi_highlight_red();
5240 off
= ansi_normal();
5241 } else if (streq_ptr(mi
.state
, "running")) {
5242 on
= ansi_highlight_green();
5243 off
= ansi_normal();
5245 on
= ansi_highlight_yellow();
5246 off
= ansi_normal();
5249 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
5251 printf(" State: %s%s%s\n",
5252 on
, strna(mi
.state
), off
);
5254 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
5255 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
5257 printf(" Since: %s; %s\n",
5258 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
5259 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
5261 printf(" CGroup: %s\n", mi
.control_group
?: "/");
5262 if (IN_SET(arg_transport
,
5263 BUS_TRANSPORT_LOCAL
,
5264 BUS_TRANSPORT_MACHINE
)) {
5265 static const char prefix
[] = " ";
5269 if (c
> sizeof(prefix
) - 1)
5270 c
-= sizeof(prefix
) - 1;
5274 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
5280 static int show(int argc
, char *argv
[], void *userdata
) {
5281 bool show_properties
, show_status
, show_help
, new_line
= false;
5282 bool ellipsized
= false;
5288 show_properties
= streq(argv
[0], "show");
5289 show_status
= streq(argv
[0], "status");
5290 show_help
= streq(argv
[0], "help");
5292 if (show_help
&& argc
<= 1) {
5293 log_error("This command expects one or more unit names. Did you mean --help?");
5297 r
= acquire_bus(BUS_MANAGER
, &bus
);
5301 pager_open(arg_no_pager
, false);
5304 /* Increase max number of open files to 16K if we can, we
5305 * might needs this when browsing journal files, which might
5306 * be split up into many files. */
5307 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
5309 /* If no argument is specified inspect the manager itself */
5310 if (show_properties
&& argc
<= 1)
5311 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", NULL
, show_properties
, &new_line
, &ellipsized
);
5313 if (show_status
&& argc
<= 1) {
5315 show_system_status(bus
);
5319 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
5321 _cleanup_free_
char **patterns
= NULL
;
5324 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
5325 _cleanup_free_
char *path
= NULL
, *unit
= NULL
;
5328 if (safe_atou32(*name
, &id
) < 0) {
5329 if (strv_push(&patterns
, *name
) < 0)
5333 } else if (show_properties
) {
5334 /* Interpret as job id */
5335 if (asprintf(&path
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
5339 /* Interpret as PID */
5340 r
= get_unit_dbus_path_by_pid(bus
, id
, &path
);
5346 r
= unit_name_from_dbus_path(path
, &unit
);
5351 r
= show_one(argv
[0], bus
, path
, unit
, show_properties
, &new_line
, &ellipsized
);
5354 else if (r
> 0 && ret
== 0)
5358 if (!strv_isempty(patterns
)) {
5359 _cleanup_strv_free_
char **names
= NULL
;
5361 r
= expand_names(bus
, patterns
, NULL
, &names
);
5363 return log_error_errno(r
, "Failed to expand names: %m");
5365 STRV_FOREACH(name
, names
) {
5366 _cleanup_free_
char *path
;
5368 path
= unit_dbus_path_from_name(*name
);
5372 r
= show_one(argv
[0], bus
, path
, *name
, show_properties
, &new_line
, &ellipsized
);
5375 if (r
> 0 && ret
== 0)
5381 if (ellipsized
&& !arg_quiet
)
5382 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5387 static int cat_file(const char *filename
, bool newline
) {
5388 _cleanup_close_
int fd
;
5390 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
5394 printf("%s%s# %s%s\n",
5395 newline
? "\n" : "",
5396 ansi_highlight_blue(),
5401 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, 0);
5404 static int cat(int argc
, char *argv
[], void *userdata
) {
5405 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5406 _cleanup_strv_free_
char **names
= NULL
;
5412 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5413 log_error("Cannot remotely cat units.");
5417 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
5419 return log_error_errno(r
, "Failed to determine unit paths: %m");
5421 r
= acquire_bus(BUS_MANAGER
, &bus
);
5425 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5427 return log_error_errno(r
, "Failed to expand names: %m");
5429 pager_open(arg_no_pager
, false);
5431 STRV_FOREACH(name
, names
) {
5432 _cleanup_free_
char *fragment_path
= NULL
;
5433 _cleanup_strv_free_
char **dropin_paths
= NULL
;
5436 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
5447 if (need_daemon_reload(bus
, *name
) > 0) /* ignore errors (<0), this is informational output */
5449 "%s# Warning: %s changed on disk, the version systemd has loaded is outdated.\n"
5450 "%s# This output shows the current version of the unit's original fragment and drop-in files.\n"
5451 "%s# If fragments or drop-ins were added or removed, they are not properly reflected in this output.\n"
5452 "%s# Run 'systemctl%s daemon-reload' to reload units.%s\n",
5453 ansi_highlight_red(),
5455 ansi_highlight_red(),
5456 ansi_highlight_red(),
5457 ansi_highlight_red(),
5458 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
5461 if (fragment_path
) {
5462 r
= cat_file(fragment_path
, false);
5464 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
5467 STRV_FOREACH(path
, dropin_paths
) {
5468 r
= cat_file(*path
, path
== dropin_paths
);
5470 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
5477 static int set_property(int argc
, char *argv
[], void *userdata
) {
5478 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5479 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5480 _cleanup_free_
char *n
= NULL
;
5484 r
= acquire_bus(BUS_MANAGER
, &bus
);
5488 polkit_agent_open_maybe();
5490 r
= sd_bus_message_new_method_call(
5493 "org.freedesktop.systemd1",
5494 "/org/freedesktop/systemd1",
5495 "org.freedesktop.systemd1.Manager",
5496 "SetUnitProperties");
5498 return bus_log_create_error(r
);
5500 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
5502 return log_error_errno(r
, "Failed to mangle unit name: %m");
5504 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
5506 return bus_log_create_error(r
);
5508 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
5510 return bus_log_create_error(r
);
5512 r
= bus_append_unit_property_assignment_many(m
, strv_skip(argv
, 2));
5516 r
= sd_bus_message_close_container(m
);
5518 return bus_log_create_error(r
);
5520 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5522 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
5527 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5528 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5529 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5534 r
= acquire_bus(BUS_MANAGER
, &bus
);
5538 polkit_agent_open_maybe();
5540 switch (arg_action
) {
5547 method
= "Reexecute";
5550 case ACTION_SYSTEMCTL
:
5551 method
= streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5552 /* "daemon-reload" */ "Reload";
5556 assert_not_reached("Unexpected action");
5559 r
= sd_bus_message_new_method_call(
5562 "org.freedesktop.systemd1",
5563 "/org/freedesktop/systemd1",
5564 "org.freedesktop.systemd1.Manager",
5567 return bus_log_create_error(r
);
5569 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5570 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5571 * their timeout, and for everything else there's the same time budget in place. */
5573 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
5575 /* On reexecution, we expect a disconnect, not a reply */
5576 if (IN_SET(r
, -ETIMEDOUT
, -ECONNRESET
) && streq(method
, "Reexecute"))
5579 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5580 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5582 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5583 * old ways of doing things, hence don't log any error in that case here. */
5585 return r
< 0 ? r
: 0;
5588 static int trivial_method(int argc
, char *argv
[], void *userdata
) {
5589 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5594 r
= acquire_bus(BUS_MANAGER
, &bus
);
5598 polkit_agent_open_maybe();
5601 streq(argv
[0], "clear-jobs") ||
5602 streq(argv
[0], "cancel") ? "ClearJobs" :
5603 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5604 streq(argv
[0], "halt") ? "Halt" :
5605 streq(argv
[0], "reboot") ? "Reboot" :
5606 streq(argv
[0], "kexec") ? "KExec" :
5607 streq(argv
[0], "exit") ? "Exit" :
5608 /* poweroff */ "PowerOff";
5610 r
= sd_bus_call_method(
5612 "org.freedesktop.systemd1",
5613 "/org/freedesktop/systemd1",
5614 "org.freedesktop.systemd1.Manager",
5619 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5620 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5622 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5623 * old ways of doing things, hence don't log any error in that case here. */
5625 return r
< 0 ? r
: 0;
5628 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5629 _cleanup_strv_free_
char **names
= NULL
;
5635 return trivial_method(argc
, argv
, userdata
);
5637 r
= acquire_bus(BUS_MANAGER
, &bus
);
5641 polkit_agent_open_maybe();
5643 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5645 return log_error_errno(r
, "Failed to expand names: %m");
5647 STRV_FOREACH(name
, names
) {
5648 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5650 q
= sd_bus_call_method(
5652 "org.freedesktop.systemd1",
5653 "/org/freedesktop/systemd1",
5654 "org.freedesktop.systemd1.Manager",
5660 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5669 static int print_variable(const char *s
) {
5671 _cleanup_free_
char *esc
= NULL
;
5673 sep
= strchr(s
, '=');
5675 log_error("Invalid environment block");
5679 esc
= shell_maybe_quote(sep
+ 1, ESCAPE_POSIX
);
5683 printf("%.*s=%s\n", (int)(sep
-s
), s
, esc
);
5687 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5688 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5689 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5694 r
= acquire_bus(BUS_MANAGER
, &bus
);
5698 pager_open(arg_no_pager
, false);
5700 r
= sd_bus_get_property(
5702 "org.freedesktop.systemd1",
5703 "/org/freedesktop/systemd1",
5704 "org.freedesktop.systemd1.Manager",
5710 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5712 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5714 return bus_log_parse_error(r
);
5716 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0) {
5717 r
= print_variable(text
);
5722 return bus_log_parse_error(r
);
5724 r
= sd_bus_message_exit_container(reply
);
5726 return bus_log_parse_error(r
);
5731 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5732 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5733 _cleanup_free_
char *cmdline_init
= NULL
;
5734 const char *root
, *init
;
5738 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5739 log_error("Cannot switch root remotely.");
5743 if (argc
< 2 || argc
> 3) {
5744 log_error("Wrong number of arguments.");
5753 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5754 "init", &cmdline_init
,
5757 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5759 init
= cmdline_init
;
5762 init
= empty_to_null(init
);
5764 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5766 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5767 root_init_path
= strjoina(root
, "/", init
);
5769 /* If the passed init is actually the same as the
5770 * systemd binary, then let's suppress it. */
5771 if (files_same(root_init_path
, root_systemd_path
, 0) > 0)
5775 /* Instruct PID1 to exclude us from its killing spree applied during
5776 * the transition. Otherwise we would exit with a failure status even
5777 * though the switch to the new root has succeed. */
5778 argv_cmdline
[0] = '@';
5780 r
= acquire_bus(BUS_MANAGER
, &bus
);
5784 /* If we are slow to exit after the root switch, the new systemd instance
5785 * will send us a signal to terminate. Just ignore it and exit normally.
5786 * This way the unit does not end up as failed.
5788 r
= ignore_signals(SIGTERM
, -1);
5790 log_warning_errno(r
, "Failed to change disposition of SIGTERM to ignore: %m");
5792 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5794 r
= sd_bus_call_method(
5796 "org.freedesktop.systemd1",
5797 "/org/freedesktop/systemd1",
5798 "org.freedesktop.systemd1.Manager",
5804 (void) default_signals(SIGTERM
, -1);
5806 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5812 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5813 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5814 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5822 r
= acquire_bus(BUS_MANAGER
, &bus
);
5826 polkit_agent_open_maybe();
5828 method
= streq(argv
[0], "set-environment")
5830 : "UnsetEnvironment";
5832 r
= sd_bus_message_new_method_call(
5835 "org.freedesktop.systemd1",
5836 "/org/freedesktop/systemd1",
5837 "org.freedesktop.systemd1.Manager",
5840 return bus_log_create_error(r
);
5842 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5844 return bus_log_create_error(r
);
5846 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5848 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5853 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5854 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5855 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5859 r
= acquire_bus(BUS_MANAGER
, &bus
);
5863 polkit_agent_open_maybe();
5865 r
= sd_bus_message_new_method_call(
5868 "org.freedesktop.systemd1",
5869 "/org/freedesktop/systemd1",
5870 "org.freedesktop.systemd1.Manager",
5873 return bus_log_create_error(r
);
5876 r
= sd_bus_message_append_strv(m
, environ
);
5880 r
= sd_bus_message_open_container(m
, 'a', "s");
5882 return bus_log_create_error(r
);
5884 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5886 if (!env_name_is_valid(*a
)) {
5887 log_error("Not a valid environment variable name: %s", *a
);
5891 STRV_FOREACH(b
, environ
) {
5894 eq
= startswith(*b
, *a
);
5895 if (eq
&& *eq
== '=') {
5897 r
= sd_bus_message_append(m
, "s", *b
);
5899 return bus_log_create_error(r
);
5906 r
= sd_bus_message_close_container(m
);
5909 return bus_log_create_error(r
);
5911 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5913 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5918 static int enable_sysv_units(const char *verb
, char **args
) {
5921 #if HAVE_SYSV_COMPAT
5922 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5925 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5927 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5930 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5933 if (!STR_IN_SET(verb
,
5939 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5946 const char *argv
[] = {
5947 ROOTLIBEXECDIR
"/systemd-sysv-install",
5954 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5955 bool found_native
= false, found_sysv
;
5964 if (!endswith(name
, ".service"))
5967 if (path_is_absolute(name
))
5970 j
= unit_file_exists(arg_scope
, &paths
, name
);
5971 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5972 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5973 found_native
= j
!= 0;
5975 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5976 * prefer the native unit */
5977 if (found_native
&& streq(verb
, "is-enabled"))
5980 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5984 p
[strlen(p
) - strlen(".service")] = 0;
5985 found_sysv
= access(p
, F_OK
) >= 0;
5991 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5993 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5996 if (!isempty(arg_root
))
5997 argv
[c
++] = q
= strappend("--root=", arg_root
);
6000 argv
[c
++] = basename(p
);
6003 l
= strv_join((char**)argv
, " ");
6008 log_info("Executing: %s", l
);
6012 return log_error_errno(errno
, "Failed to fork: %m");
6013 else if (pid
== 0) {
6016 (void) reset_all_signal_handlers();
6017 (void) reset_signal_mask();
6019 execv(argv
[0], (char**) argv
);
6020 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
6021 _exit(EXIT_FAILURE
);
6024 j
= wait_for_terminate(pid
, &status
);
6026 return log_error_errno(j
, "Failed to wait for child: %m");
6028 if (status
.si_code
== CLD_EXITED
) {
6029 if (streq(verb
, "is-enabled")) {
6030 if (status
.si_status
== 0) {
6039 } else if (status
.si_status
!= 0)
6040 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
6042 log_error("Unexpected waitid() result.");
6049 /* Remove this entry, so that we don't try enabling it as native unit */
6052 assert(args
[f
] == name
);
6053 strv_remove(args
, name
);
6060 static int mangle_names(char **original_names
, char ***mangled_names
) {
6061 char **i
, **l
, **name
;
6064 l
= i
= new(char*, strv_length(original_names
) + 1);
6068 STRV_FOREACH(name
, original_names
) {
6070 /* When enabling units qualified path names are OK,
6071 * too, hence allow them explicitly. */
6073 if (is_path(*name
)) {
6080 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
6084 return log_error_errno(r
, "Failed to mangle unit name: %m");
6097 static int normalize_filenames(char **names
) {
6101 STRV_FOREACH(u
, names
)
6102 if (!path_is_absolute(*u
)) {
6103 char* normalized_path
;
6105 if (!isempty(arg_root
)) {
6106 log_error("Non-absolute paths are not allowed when --root is used: %s", *u
);
6110 if (!strchr(*u
,'/')) {
6111 log_error("Link argument does contain at least one directory separator: %s", *u
);
6115 r
= path_make_absolute_cwd(*u
, &normalized_path
);
6119 free_and_replace(*u
, normalized_path
);
6125 static int normalize_names(char **names
, bool warn_if_path
) {
6127 bool was_path
= false;
6129 STRV_FOREACH(u
, names
) {
6135 r
= free_and_strdup(u
, basename(*u
));
6137 return log_error_errno(r
, "Failed to normalize unit file path: %m");
6142 if (warn_if_path
&& was_path
)
6143 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
6148 static int unit_exists(LookupPaths
*lp
, const char *unit
) {
6149 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6150 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6151 _cleanup_free_
char *path
= NULL
;
6152 static const struct bus_properties_map property_map
[] = {
6153 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
6154 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
)},
6157 UnitStatusInfo info
= {};
6161 if (unit_name_is_valid(unit
, UNIT_NAME_TEMPLATE
))
6162 return unit_find_template_path(unit
, lp
, NULL
, NULL
);
6164 path
= unit_dbus_path_from_name(unit
);
6168 r
= acquire_bus(BUS_MANAGER
, &bus
);
6172 r
= sd_bus_call_method(
6174 "org.freedesktop.systemd1",
6176 "org.freedesktop.DBus.Properties",
6182 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
6184 r
= bus_message_map_all_properties(reply
, property_map
, &error
, &info
);
6186 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
6188 return !streq_ptr(info
.load_state
, "not-found") || !streq_ptr(info
.active_state
, "inactive");
6191 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
6192 _cleanup_strv_free_
char **names
= NULL
;
6193 const char *verb
= argv
[0];
6194 UnitFileChange
*changes
= NULL
;
6195 unsigned n_changes
= 0;
6196 int carries_install_info
= -1;
6197 bool ignore_carries_install_info
= arg_quiet
;
6203 r
= mangle_names(strv_skip(argv
, 1), &names
);
6207 r
= enable_sysv_units(verb
, names
);
6211 /* If the operation was fully executed by the SysV compat, let's finish early */
6212 if (strv_isempty(names
)) {
6213 if (arg_no_reload
|| install_client_side())
6215 return daemon_reload(argc
, argv
, userdata
);
6218 if (streq(verb
, "disable")) {
6219 r
= normalize_names(names
, true);
6224 if (streq(verb
, "link")) {
6225 r
= normalize_filenames(names
);
6230 if (install_client_side()) {
6231 UnitFileFlags flags
;
6233 flags
= args_to_flags();
6234 if (streq(verb
, "enable")) {
6235 r
= unit_file_enable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6236 carries_install_info
= r
;
6237 } else if (streq(verb
, "disable"))
6238 r
= unit_file_disable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6239 else if (streq(verb
, "reenable")) {
6240 r
= unit_file_reenable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6241 carries_install_info
= r
;
6242 } else if (streq(verb
, "link"))
6243 r
= unit_file_link(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6244 else if (streq(verb
, "preset")) {
6245 r
= unit_file_preset(arg_scope
, flags
, arg_root
, names
, arg_preset_mode
, &changes
, &n_changes
);
6246 } else if (streq(verb
, "mask"))
6247 r
= unit_file_mask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6248 else if (streq(verb
, "unmask"))
6249 r
= unit_file_unmask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6250 else if (streq(verb
, "revert"))
6251 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
6253 assert_not_reached("Unknown verb");
6255 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
6260 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6261 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6262 bool expect_carries_install_info
= false;
6263 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
6267 if (STR_IN_SET(verb
, "mask", "unmask")) {
6269 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6271 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6275 STRV_FOREACH(name
, names
) {
6276 r
= unit_exists(&lp
, *name
);
6280 log_notice("Unit %s does not exist, proceeding anyway.", *names
);
6284 r
= acquire_bus(BUS_MANAGER
, &bus
);
6288 polkit_agent_open_maybe();
6290 if (streq(verb
, "enable")) {
6291 method
= "EnableUnitFiles";
6292 expect_carries_install_info
= true;
6293 } else if (streq(verb
, "disable")) {
6294 method
= "DisableUnitFiles";
6296 } else if (streq(verb
, "reenable")) {
6297 method
= "ReenableUnitFiles";
6298 expect_carries_install_info
= true;
6299 } else if (streq(verb
, "link"))
6300 method
= "LinkUnitFiles";
6301 else if (streq(verb
, "preset")) {
6303 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
6304 method
= "PresetUnitFilesWithMode";
6305 send_preset_mode
= true;
6307 method
= "PresetUnitFiles";
6309 expect_carries_install_info
= true;
6310 ignore_carries_install_info
= true;
6311 } else if (streq(verb
, "mask"))
6312 method
= "MaskUnitFiles";
6313 else if (streq(verb
, "unmask")) {
6314 method
= "UnmaskUnitFiles";
6316 } else if (streq(verb
, "revert")) {
6317 method
= "RevertUnitFiles";
6318 send_runtime
= send_force
= false;
6320 assert_not_reached("Unknown verb");
6322 r
= sd_bus_message_new_method_call(
6325 "org.freedesktop.systemd1",
6326 "/org/freedesktop/systemd1",
6327 "org.freedesktop.systemd1.Manager",
6330 return bus_log_create_error(r
);
6332 r
= sd_bus_message_append_strv(m
, names
);
6334 return bus_log_create_error(r
);
6336 if (send_preset_mode
) {
6337 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
6339 return bus_log_create_error(r
);
6343 r
= sd_bus_message_append(m
, "b", arg_runtime
);
6345 return bus_log_create_error(r
);
6349 r
= sd_bus_message_append(m
, "b", arg_force
);
6351 return bus_log_create_error(r
);
6354 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6356 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
6358 if (expect_carries_install_info
) {
6359 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
6361 return bus_log_parse_error(r
);
6364 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6368 /* Try to reload if enabled */
6370 r
= daemon_reload(argc
, argv
, userdata
);
6375 if (carries_install_info
== 0 && !ignore_carries_install_info
)
6376 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6377 "settings in the [Install] section, and DefaultInstance for template units).\n"
6378 "This means they are not meant to be enabled using systemctl.\n"
6379 "Possible reasons for having this kind of units are:\n"
6380 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6381 " .wants/ or .requires/ directory.\n"
6382 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6383 " a requirement dependency on it.\n"
6384 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6385 " D-Bus, udev, scripted systemctl call, ...).\n"
6386 "4) In case of template units, the unit is meant to be enabled with some\n"
6387 " instance name specified.");
6389 if (arg_now
&& STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
6393 r
= acquire_bus(BUS_MANAGER
, &bus
);
6397 len
= strv_length(names
);
6399 char *new_args
[len
+ 2];
6401 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
6402 for (i
= 0; i
< len
; i
++)
6403 new_args
[i
+ 1] = basename(names
[i
]);
6404 new_args
[i
+ 1] = NULL
;
6406 r
= start_unit(len
+ 1, new_args
, userdata
);
6411 unit_file_changes_free(changes
, n_changes
);
6416 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
6417 _cleanup_strv_free_
char **names
= NULL
;
6418 _cleanup_free_
char *target
= NULL
;
6419 const char *verb
= argv
[0];
6420 UnitFileChange
*changes
= NULL
;
6421 unsigned n_changes
= 0;
6428 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
6430 return log_error_errno(r
, "Failed to mangle unit name: %m");
6432 r
= mangle_names(strv_skip(argv
, 2), &names
);
6436 if (streq(verb
, "add-wants"))
6438 else if (streq(verb
, "add-requires"))
6439 dep
= UNIT_REQUIRES
;
6441 assert_not_reached("Unknown verb");
6443 if (install_client_side()) {
6444 r
= unit_file_add_dependency(arg_scope
, args_to_flags(), arg_root
, names
, target
, dep
, &changes
, &n_changes
);
6445 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
6450 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6451 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6454 r
= acquire_bus(BUS_MANAGER
, &bus
);
6458 polkit_agent_open_maybe();
6460 r
= sd_bus_message_new_method_call(
6463 "org.freedesktop.systemd1",
6464 "/org/freedesktop/systemd1",
6465 "org.freedesktop.systemd1.Manager",
6466 "AddDependencyUnitFiles");
6468 return bus_log_create_error(r
);
6470 r
= sd_bus_message_append_strv(m
, names
);
6472 return bus_log_create_error(r
);
6474 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
6476 return bus_log_create_error(r
);
6478 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6480 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
6482 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6486 if (arg_no_reload
) {
6491 r
= daemon_reload(argc
, argv
, userdata
);
6495 unit_file_changes_free(changes
, n_changes
);
6500 static int preset_all(int argc
, char *argv
[], void *userdata
) {
6501 UnitFileChange
*changes
= NULL
;
6502 unsigned n_changes
= 0;
6505 if (install_client_side()) {
6506 r
= unit_file_preset_all(arg_scope
, args_to_flags(), arg_root
, arg_preset_mode
, &changes
, &n_changes
);
6507 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
6512 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6513 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6516 r
= acquire_bus(BUS_MANAGER
, &bus
);
6520 polkit_agent_open_maybe();
6522 r
= sd_bus_call_method(
6524 "org.freedesktop.systemd1",
6525 "/org/freedesktop/systemd1",
6526 "org.freedesktop.systemd1.Manager",
6527 "PresetAllUnitFiles",
6531 unit_file_preset_mode_to_string(arg_preset_mode
),
6535 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
6537 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6541 if (arg_no_reload
) {
6546 r
= daemon_reload(argc
, argv
, userdata
);
6550 unit_file_changes_free(changes
, n_changes
);
6555 static int show_installation_targets_client_side(const char *name
) {
6556 UnitFileChange
*changes
= NULL
;
6557 unsigned n_changes
= 0, i
;
6558 UnitFileFlags flags
;
6562 p
= STRV_MAKE(name
);
6563 flags
= UNIT_FILE_DRY_RUN
|
6564 (arg_runtime
? UNIT_FILE_RUNTIME
: 0);
6566 r
= unit_file_disable(UNIT_FILE_SYSTEM
, flags
, NULL
, p
, &changes
, &n_changes
);
6568 return log_error_errno(r
, "Failed to get file links for %s: %m", name
);
6570 for (i
= 0; i
< n_changes
; i
++)
6571 if (changes
[i
].type
== UNIT_FILE_UNLINK
)
6572 printf(" %s\n", changes
[i
].path
);
6577 static int show_installation_targets(sd_bus
*bus
, const char *name
) {
6578 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6579 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6583 r
= sd_bus_call_method(
6585 "org.freedesktop.systemd1",
6586 "/org/freedesktop/systemd1",
6587 "org.freedesktop.systemd1.Manager",
6591 "sb", name
, arg_runtime
);
6593 return log_error_errno(r
, "Failed to get unit file links for %s: %s", name
, bus_error_message(&error
, r
));
6595 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
6597 return bus_log_parse_error(r
);
6599 while ((r
= sd_bus_message_read(reply
, "s", &link
)) > 0)
6600 printf(" %s\n", link
);
6603 return bus_log_parse_error(r
);
6605 r
= sd_bus_message_exit_container(reply
);
6607 return bus_log_parse_error(r
);
6612 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
6614 _cleanup_strv_free_
char **names
= NULL
;
6619 r
= mangle_names(strv_skip(argv
, 1), &names
);
6623 r
= enable_sysv_units(argv
[0], names
);
6629 if (install_client_side()) {
6630 STRV_FOREACH(name
, names
) {
6631 UnitFileState state
;
6633 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
6635 return log_error_errno(r
, "Failed to get unit file state for %s: %m", *name
);
6639 UNIT_FILE_ENABLED_RUNTIME
,
6642 UNIT_FILE_GENERATED
))
6646 puts(unit_file_state_to_string(state
));
6648 r
= show_installation_targets_client_side(*name
);
6657 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6660 r
= acquire_bus(BUS_MANAGER
, &bus
);
6664 STRV_FOREACH(name
, names
) {
6665 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6668 r
= sd_bus_call_method(
6670 "org.freedesktop.systemd1",
6671 "/org/freedesktop/systemd1",
6672 "org.freedesktop.systemd1.Manager",
6678 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
6680 r
= sd_bus_message_read(reply
, "s", &s
);
6682 return bus_log_parse_error(r
);
6684 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6690 r
= show_installation_targets(bus
, *name
);
6698 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
6701 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
6702 _cleanup_free_
char *state
= NULL
;
6706 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
6709 return EXIT_FAILURE
;
6712 r
= acquire_bus(BUS_MANAGER
, &bus
);
6716 r
= sd_bus_get_property_string(
6718 "org.freedesktop.systemd1",
6719 "/org/freedesktop/systemd1",
6720 "org.freedesktop.systemd1.Manager",
6733 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
6736 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
6737 _cleanup_free_
char *t
= NULL
;
6741 assert(original_path
);
6744 r
= tempfn_random(new_path
, NULL
, &t
);
6746 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
6748 r
= mkdir_parents(new_path
, 0755);
6750 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
6752 r
= copy_file(original_path
, t
, 0, 0644, 0, COPY_REFLINK
);
6757 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
6760 return log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", new_path
);
6768 static int get_file_to_edit(
6769 const LookupPaths
*paths
,
6773 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
6778 path
= strjoin(paths
->persistent_config
, "/", name
);
6783 run
= strjoin(paths
->runtime_config
, "/", name
);
6789 if (access(path
, F_OK
) >= 0) {
6790 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
6804 static int unit_file_create_new(
6805 const LookupPaths
*paths
,
6806 const char *unit_name
,
6808 char **ret_new_path
,
6809 char **ret_tmp_path
) {
6811 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6815 assert(ret_new_path
);
6816 assert(ret_tmp_path
);
6818 ending
= strjoina(unit_name
, suffix
);
6819 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
6823 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6829 *ret_new_path
= tmp_new_path
;
6830 *ret_tmp_path
= tmp_tmp_path
;
6835 static int unit_file_create_copy(
6836 const LookupPaths
*paths
,
6837 const char *unit_name
,
6838 const char *fragment_path
,
6839 char **ret_new_path
,
6840 char **ret_tmp_path
) {
6842 char *tmp_new_path
, *tmp_tmp_path
;
6845 assert(fragment_path
);
6847 assert(ret_new_path
);
6848 assert(ret_tmp_path
);
6850 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6854 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6857 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6862 if (response
!= 'y') {
6863 log_warning("%s ignored", unit_name
);
6865 return -EKEYREJECTED
;
6869 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6875 *ret_new_path
= tmp_new_path
;
6876 *ret_tmp_path
= tmp_tmp_path
;
6881 static int run_editor(char **paths
) {
6889 return log_error_errno(errno
, "Failed to fork: %m");
6893 char *editor
, **editor_args
= NULL
;
6894 char **tmp_path
, **original_path
, *p
;
6895 unsigned n_editor_args
= 0, i
= 1;
6898 (void) reset_all_signal_handlers();
6899 (void) reset_signal_mask();
6901 argc
= strv_length(paths
)/2 + 1;
6903 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6904 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6905 * we try to execute well known editors
6907 editor
= getenv("SYSTEMD_EDITOR");
6909 editor
= getenv("EDITOR");
6911 editor
= getenv("VISUAL");
6913 if (!isempty(editor
)) {
6914 editor_args
= strv_split(editor
, WHITESPACE
);
6917 _exit(EXIT_FAILURE
);
6919 n_editor_args
= strv_length(editor_args
);
6920 argc
+= n_editor_args
- 1;
6922 args
= newa(const char*, argc
+ 1);
6924 if (n_editor_args
> 0) {
6925 args
[0] = editor_args
[0];
6926 for (; i
< n_editor_args
; i
++)
6927 args
[i
] = editor_args
[i
];
6930 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6931 args
[i
] = *tmp_path
;
6936 if (n_editor_args
> 0)
6937 execvp(args
[0], (char* const*) args
);
6939 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6941 execvp(p
, (char* const*) args
);
6942 /* We do not fail if the editor doesn't exist
6943 * because we want to try each one of them before
6946 if (errno
!= ENOENT
) {
6947 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6948 _exit(EXIT_FAILURE
);
6952 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6953 _exit(EXIT_FAILURE
);
6956 r
= wait_for_terminate_and_warn("editor", pid
, true);
6958 return log_error_errno(r
, "Failed to wait for child: %m");
6963 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6964 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6971 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6975 STRV_FOREACH(name
, names
) {
6976 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
, *tmp_name
= NULL
;
6977 const char *unit_name
;
6979 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6987 log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
6988 arg_scope
== UNIT_FILE_GLOBAL
? " --global" :
6989 arg_scope
== UNIT_FILE_USER
? " --user" : "",
6994 /* Create a new unit from scratch */
6996 r
= unit_file_create_new(&lp
, unit_name
,
6997 arg_full
? NULL
: ".d/override.conf",
6998 &new_path
, &tmp_path
);
7002 unit_name
= basename(path
);
7003 /* We follow unit aliases, but we need to propagate the instance */
7004 if (unit_name_is_valid(*name
, UNIT_NAME_INSTANCE
) &&
7005 unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
7006 _cleanup_free_
char *instance
= NULL
;
7008 r
= unit_name_to_instance(*name
, &instance
);
7012 r
= unit_name_replace_instance(unit_name
, instance
, &tmp_name
);
7016 unit_name
= tmp_name
;
7020 r
= unit_file_create_copy(&lp
, unit_name
, path
, &new_path
, &tmp_path
);
7022 r
= unit_file_create_new(&lp
, unit_name
, ".d/override.conf", &new_path
, &tmp_path
);
7027 r
= strv_push_pair(paths
, new_path
, tmp_path
);
7030 new_path
= tmp_path
= NULL
;
7036 static int edit(int argc
, char *argv
[], void *userdata
) {
7037 _cleanup_strv_free_
char **names
= NULL
;
7038 _cleanup_strv_free_
char **paths
= NULL
;
7039 char **original
, **tmp
;
7044 log_error("Cannot edit units if not on a tty.");
7048 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
7049 log_error("Cannot edit units remotely.");
7053 r
= acquire_bus(BUS_MANAGER
, &bus
);
7057 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
7059 return log_error_errno(r
, "Failed to expand names: %m");
7061 r
= find_paths_to_edit(bus
, names
, &paths
);
7065 if (strv_isempty(paths
))
7068 r
= run_editor(paths
);
7072 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
7073 /* If the temporary file is empty we ignore it. It's
7074 * useful if the user wants to cancel its modification
7076 if (null_or_empty_path(*tmp
)) {
7077 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
7081 r
= rename(*tmp
, *original
);
7083 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
7090 if (!arg_no_reload
&& !install_client_side())
7091 r
= daemon_reload(argc
, argv
, userdata
);
7094 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
7095 (void) unlink(*tmp
);
7097 /* Removing empty dropin dirs */
7099 _cleanup_free_
char *dir
;
7101 dir
= dirname_malloc(*original
);
7105 /* no need to check if the dir is empty, rmdir
7106 * does nothing if it is not the case.
7115 static void systemctl_help(void) {
7117 pager_open(arg_no_pager
, false);
7119 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
7120 "Query or send control commands to the systemd manager.\n\n"
7121 " -h --help Show this help\n"
7122 " --version Show package version\n"
7123 " --system Connect to system manager\n"
7124 " --user Connect to user service manager\n"
7125 " -H --host=[USER@]HOST\n"
7126 " Operate on remote host\n"
7127 " -M --machine=CONTAINER\n"
7128 " Operate on local container\n"
7129 " -t --type=TYPE List units of a particular type\n"
7130 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
7131 " -p --property=NAME Show only properties by this name\n"
7132 " -a --all Show all properties/all units currently in memory,\n"
7133 " including dead/empty ones. To list all units installed on\n"
7134 " the system, use the 'list-unit-files' command instead.\n"
7135 " --failed Same as --state=failed\n"
7136 " -l --full Don't ellipsize unit names on output\n"
7137 " -r --recursive Show unit list of host and local containers\n"
7138 " --reverse Show reverse dependencies with 'list-dependencies'\n"
7139 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
7140 " queueing a new job\n"
7141 " --show-types When showing sockets, explicitly show their type\n"
7142 " --value When showing properties, only print the value\n"
7143 " -i --ignore-inhibitors\n"
7144 " When shutting down or sleeping, ignore inhibitors\n"
7145 " --kill-who=WHO Who to send signal to\n"
7146 " -s --signal=SIGNAL Which signal to send\n"
7147 " --now Start or stop unit in addition to enabling or disabling it\n"
7148 " -q --quiet Suppress output\n"
7149 " --wait For (re)start, wait until service stopped again\n"
7150 " --no-block Do not wait until operation finished\n"
7151 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7152 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
7153 " --no-legend Do not print a legend (column headers and hints)\n"
7154 " --no-pager Do not pipe output into a pager\n"
7155 " --no-ask-password\n"
7156 " Do not ask for system passwords\n"
7157 " --global Enable/disable/mask unit files globally\n"
7158 " --runtime Enable/disable/mask unit files temporarily until next\n"
7160 " -f --force When enabling unit files, override existing symlinks\n"
7161 " When shutting down, execute action immediately\n"
7162 " --preset-mode= Apply only enable, only disable, or all presets\n"
7163 " --root=PATH Enable/disable/mask unit files in the specified root\n"
7165 " -n --lines=INTEGER Number of journal entries to show\n"
7166 " -o --output=STRING Change journal output mode (short, short-precise,\n"
7167 " short-iso, short-iso-precise, short-full,\n"
7168 " short-monotonic, short-unix,\n"
7169 " verbose, export, json, json-pretty, json-sse, cat)\n"
7170 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
7171 " --plain Print unit dependencies as a list instead of a tree\n\n"
7173 " list-units [PATTERN...] List units currently in memory\n"
7174 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
7176 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
7178 " start NAME... Start (activate) one or more units\n"
7179 " stop NAME... Stop (deactivate) one or more units\n"
7180 " reload NAME... Reload one or more units\n"
7181 " restart NAME... Start or restart one or more units\n"
7182 " try-restart NAME... Restart one or more units if active\n"
7183 " reload-or-restart NAME... Reload one or more units if possible,\n"
7184 " otherwise start or restart\n"
7185 " try-reload-or-restart NAME... If active, reload one or more units,\n"
7186 " if supported, otherwise restart\n"
7187 " isolate NAME Start one unit and stop all others\n"
7188 " kill NAME... Send signal to processes of a unit\n"
7189 " is-active PATTERN... Check whether units are active\n"
7190 " is-failed PATTERN... Check whether units are failed\n"
7191 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
7192 " show [PATTERN...|JOB...] Show properties of one or more\n"
7193 " units/jobs or the manager\n"
7194 " cat PATTERN... Show files and drop-ins of one or more units\n"
7195 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
7196 " help PATTERN...|PID... Show manual for one or more units\n"
7197 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
7199 " list-dependencies [NAME] Recursively show units which are required\n"
7200 " or wanted by this unit or by which this\n"
7201 " unit is required or wanted\n\n"
7202 "Unit File Commands:\n"
7203 " list-unit-files [PATTERN...] List installed unit files\n"
7204 " enable [NAME...|PATH...] Enable one or more unit files\n"
7205 " disable NAME... Disable one or more unit files\n"
7206 " reenable NAME... Reenable one or more unit files\n"
7207 " preset NAME... Enable/disable one or more unit files\n"
7208 " based on preset configuration\n"
7209 " preset-all Enable/disable all unit files based on\n"
7210 " preset configuration\n"
7211 " is-enabled NAME... Check whether unit files are enabled\n"
7212 " mask NAME... Mask one or more units\n"
7213 " unmask NAME... Unmask one or more units\n"
7214 " link PATH... Link one or more units files into\n"
7215 " the search path\n"
7216 " revert NAME... Revert one or more unit files to vendor\n"
7218 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
7219 " on specified one or more units\n"
7220 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
7221 " on specified one or more units\n"
7222 " edit NAME... Edit one or more unit files\n"
7223 " get-default Get the name of the default target\n"
7224 " set-default NAME Set the default target\n\n"
7225 "Machine Commands:\n"
7226 " list-machines [PATTERN...] List local containers and host\n\n"
7228 " list-jobs [PATTERN...] List jobs\n"
7229 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
7230 "Environment Commands:\n"
7231 " show-environment Dump environment\n"
7232 " set-environment NAME=VALUE... Set one or more environment variables\n"
7233 " unset-environment NAME... Unset one or more environment variables\n"
7234 " import-environment [NAME...] Import all or some environment variables\n\n"
7235 "Manager Lifecycle Commands:\n"
7236 " daemon-reload Reload systemd manager configuration\n"
7237 " daemon-reexec Reexecute systemd manager\n\n"
7238 "System Commands:\n"
7239 " is-system-running Check whether system is fully running\n"
7240 " default Enter system default mode\n"
7241 " rescue Enter system rescue mode\n"
7242 " emergency Enter system emergency mode\n"
7243 " halt Shut down and halt the system\n"
7244 " poweroff Shut down and power-off the system\n"
7245 " reboot [ARG] Shut down and reboot the system\n"
7246 " kexec Shut down and reboot the system with kexec\n"
7247 " exit [EXIT_CODE] Request user instance or container exit\n"
7248 " switch-root ROOT [INIT] Change to a different root file system\n"
7249 " suspend Suspend the system\n"
7250 " hibernate Hibernate the system\n"
7251 " hybrid-sleep Hibernate and suspend the system\n",
7252 program_invocation_short_name
);
7255 static void halt_help(void) {
7256 printf("%s [OPTIONS...]%s\n\n"
7257 "%s the system.\n\n"
7258 " --help Show this help\n"
7259 " --halt Halt the machine\n"
7260 " -p --poweroff Switch off the machine\n"
7261 " --reboot Reboot the machine\n"
7262 " -f --force Force immediate halt/power-off/reboot\n"
7263 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
7264 " -d --no-wtmp Don't write wtmp record\n"
7265 " --no-wall Don't send wall message before halt/power-off/reboot\n",
7266 program_invocation_short_name
,
7267 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
7268 arg_action
== ACTION_REBOOT
? "Reboot" :
7269 arg_action
== ACTION_POWEROFF
? "Power off" :
7273 static void shutdown_help(void) {
7274 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
7275 "Shut down the system.\n\n"
7276 " --help Show this help\n"
7277 " -H --halt Halt the machine\n"
7278 " -P --poweroff Power-off the machine\n"
7279 " -r --reboot Reboot the machine\n"
7280 " -h Equivalent to --poweroff, overridden by --halt\n"
7281 " -k Don't halt/power-off/reboot, just send warnings\n"
7282 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7283 " -c Cancel a pending shutdown\n",
7284 program_invocation_short_name
);
7287 static void telinit_help(void) {
7288 printf("%s [OPTIONS...] {COMMAND}\n\n"
7289 "Send control commands to the init daemon.\n\n"
7290 " --help Show this help\n"
7291 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7293 " 0 Power-off the machine\n"
7294 " 6 Reboot the machine\n"
7295 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7296 " 1, s, S Enter rescue mode\n"
7297 " q, Q Reload init daemon configuration\n"
7298 " u, U Reexecute init daemon\n",
7299 program_invocation_short_name
);
7302 static void runlevel_help(void) {
7303 printf("%s [OPTIONS...]\n\n"
7304 "Prints the previous and current runlevel of the init system.\n\n"
7305 " --help Show this help\n",
7306 program_invocation_short_name
);
7309 static void help_types(void) {
7313 puts("Available unit types:");
7314 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
7315 puts(unit_type_to_string(i
));
7318 static void help_states(void) {
7322 puts("Available unit load states:");
7323 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
7324 puts(unit_load_state_to_string(i
));
7327 puts("\nAvailable unit active states:");
7328 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
7329 puts(unit_active_state_to_string(i
));
7332 puts("\nAvailable automount unit substates:");
7333 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
7334 puts(automount_state_to_string(i
));
7337 puts("\nAvailable device unit substates:");
7338 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
7339 puts(device_state_to_string(i
));
7342 puts("\nAvailable mount unit substates:");
7343 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
7344 puts(mount_state_to_string(i
));
7347 puts("\nAvailable path unit substates:");
7348 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
7349 puts(path_state_to_string(i
));
7352 puts("\nAvailable scope unit substates:");
7353 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
7354 puts(scope_state_to_string(i
));
7357 puts("\nAvailable service unit substates:");
7358 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
7359 puts(service_state_to_string(i
));
7362 puts("\nAvailable slice unit substates:");
7363 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
7364 puts(slice_state_to_string(i
));
7367 puts("\nAvailable socket unit substates:");
7368 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
7369 puts(socket_state_to_string(i
));
7372 puts("\nAvailable swap unit substates:");
7373 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
7374 puts(swap_state_to_string(i
));
7377 puts("\nAvailable target unit substates:");
7378 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
7379 puts(target_state_to_string(i
));
7382 puts("\nAvailable timer unit substates:");
7383 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
7384 puts(timer_state_to_string(i
));
7387 static int systemctl_parse_argv(int argc
, char *argv
[]) {
7396 ARG_IGNORE_DEPENDENCIES
,
7409 ARG_NO_ASK_PASSWORD
,
7423 static const struct option options
[] = {
7424 { "help", no_argument
, NULL
, 'h' },
7425 { "version", no_argument
, NULL
, ARG_VERSION
},
7426 { "type", required_argument
, NULL
, 't' },
7427 { "property", required_argument
, NULL
, 'p' },
7428 { "all", no_argument
, NULL
, 'a' },
7429 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
7430 { "after", no_argument
, NULL
, ARG_AFTER
},
7431 { "before", no_argument
, NULL
, ARG_BEFORE
},
7432 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
7433 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
7434 { "full", no_argument
, NULL
, 'l' },
7435 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
7436 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
7437 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
7438 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
7439 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
7440 { "value", no_argument
, NULL
, ARG_VALUE
},
7441 { "user", no_argument
, NULL
, ARG_USER
},
7442 { "system", no_argument
, NULL
, ARG_SYSTEM
},
7443 { "global", no_argument
, NULL
, ARG_GLOBAL
},
7444 { "wait", no_argument
, NULL
, ARG_WAIT
},
7445 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
7446 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
7447 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
7448 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7449 { "quiet", no_argument
, NULL
, 'q' },
7450 { "root", required_argument
, NULL
, ARG_ROOT
},
7451 { "force", no_argument
, NULL
, ARG_FORCE
},
7452 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
7453 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
7454 { "signal", required_argument
, NULL
, 's' },
7455 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
7456 { "host", required_argument
, NULL
, 'H' },
7457 { "machine", required_argument
, NULL
, 'M' },
7458 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
7459 { "lines", required_argument
, NULL
, 'n' },
7460 { "output", required_argument
, NULL
, 'o' },
7461 { "plain", no_argument
, NULL
, ARG_PLAIN
},
7462 { "state", required_argument
, NULL
, ARG_STATE
},
7463 { "recursive", no_argument
, NULL
, 'r' },
7464 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
7465 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
7466 { "now", no_argument
, NULL
, ARG_NOW
},
7467 { "message", required_argument
, NULL
, ARG_MESSAGE
},
7477 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7478 arg_ask_password
= true;
7480 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
7492 if (isempty(optarg
)) {
7493 log_error("--type= requires arguments.");
7497 for (p
= optarg
;;) {
7498 _cleanup_free_
char *type
= NULL
;
7500 r
= extract_first_word(&p
, &type
, ",", 0);
7502 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
7506 if (streq(type
, "help")) {
7511 if (unit_type_from_string(type
) >= 0) {
7512 if (strv_push(&arg_types
, type
) < 0)
7518 /* It's much nicer to use --state= for
7519 * load states, but let's support this
7520 * in --types= too for compatibility
7521 * with old versions */
7522 if (unit_load_state_from_string(type
) >= 0) {
7523 if (strv_push(&arg_states
, type
) < 0)
7529 log_error("Unknown unit type or load state '%s'.", type
);
7530 log_info("Use -t help to see a list of allowed values.");
7538 /* Make sure that if the empty property list
7539 was specified, we won't show any properties. */
7540 if (isempty(optarg
) && !arg_properties
) {
7541 arg_properties
= new0(char*, 1);
7542 if (!arg_properties
)
7545 for (p
= optarg
;;) {
7546 _cleanup_free_
char *prop
= NULL
;
7548 r
= extract_first_word(&p
, &prop
, ",", 0);
7550 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
7554 if (strv_push(&arg_properties
, prop
) < 0)
7560 /* If the user asked for a particular
7561 * property, show it to him, even if it is
7573 arg_dependency
= DEPENDENCY_REVERSE
;
7577 arg_dependency
= DEPENDENCY_AFTER
;
7578 arg_jobs_after
= true;
7582 arg_dependency
= DEPENDENCY_BEFORE
;
7583 arg_jobs_before
= true;
7586 case ARG_SHOW_TYPES
:
7587 arg_show_types
= true;
7595 arg_job_mode
= optarg
;
7599 arg_job_mode
= "fail";
7602 case ARG_IRREVERSIBLE
:
7603 arg_job_mode
= "replace-irreversibly";
7606 case ARG_IGNORE_DEPENDENCIES
:
7607 arg_job_mode
= "ignore-dependencies";
7611 arg_scope
= UNIT_FILE_USER
;
7615 arg_scope
= UNIT_FILE_SYSTEM
;
7619 arg_scope
= UNIT_FILE_GLOBAL
;
7627 arg_no_block
= true;
7631 arg_no_legend
= true;
7635 arg_no_pager
= true;
7643 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
7653 if (strv_extend(&arg_states
, "failed") < 0)
7671 arg_no_reload
= true;
7675 arg_kill_who
= optarg
;
7679 arg_signal
= signal_from_string_try_harder(optarg
);
7680 if (arg_signal
< 0) {
7681 log_error("Failed to parse signal string %s.", optarg
);
7686 case ARG_NO_ASK_PASSWORD
:
7687 arg_ask_password
= false;
7691 arg_transport
= BUS_TRANSPORT_REMOTE
;
7696 arg_transport
= BUS_TRANSPORT_MACHINE
;
7705 if (safe_atou(optarg
, &arg_lines
) < 0) {
7706 log_error("Failed to parse lines '%s'", optarg
);
7712 arg_output
= output_mode_from_string(optarg
);
7713 if (arg_output
< 0) {
7714 log_error("Unknown output '%s'.", optarg
);
7720 arg_ignore_inhibitors
= true;
7727 case ARG_FIRMWARE_SETUP
:
7728 arg_firmware_setup
= true;
7732 if (isempty(optarg
)) {
7733 log_error("--state= requires arguments.");
7737 for (p
= optarg
;;) {
7738 _cleanup_free_
char *s
= NULL
;
7740 r
= extract_first_word(&p
, &s
, ",", 0);
7742 return log_error_errno(r
, "Failed to parse state: %s", optarg
);
7746 if (streq(s
, "help")) {
7751 if (strv_push(&arg_states
, s
) < 0)
7760 if (geteuid() != 0) {
7761 log_error("--recursive requires root privileges.");
7765 arg_recursive
= true;
7768 case ARG_PRESET_MODE
:
7770 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
7771 if (arg_preset_mode
< 0) {
7772 log_error("Failed to parse preset mode: %s.", optarg
);
7783 if (strv_extend(&arg_wall
, optarg
) < 0)
7791 assert_not_reached("Unhandled option");
7794 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
7795 log_error("Cannot access user instance remotely.");
7799 if (arg_wait
&& arg_no_block
) {
7800 log_error("--wait may not be combined with --no-block.");
7807 static int halt_parse_argv(int argc
, char *argv
[]) {
7816 static const struct option options
[] = {
7817 { "help", no_argument
, NULL
, ARG_HELP
},
7818 { "halt", no_argument
, NULL
, ARG_HALT
},
7819 { "poweroff", no_argument
, NULL
, 'p' },
7820 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
7821 { "force", no_argument
, NULL
, 'f' },
7822 { "wtmp-only", no_argument
, NULL
, 'w' },
7823 { "no-wtmp", no_argument
, NULL
, 'd' },
7824 { "no-sync", no_argument
, NULL
, 'n' },
7825 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7834 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
7835 if (IN_SET(runlevel
, '0', '6'))
7838 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
7846 arg_action
= ACTION_HALT
;
7850 if (arg_action
!= ACTION_REBOOT
)
7851 arg_action
= ACTION_POWEROFF
;
7855 arg_action
= ACTION_REBOOT
;
7880 /* Compatibility nops */
7887 assert_not_reached("Unhandled option");
7890 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7891 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7894 } else if (optind
< argc
) {
7895 log_error("Too many arguments.");
7902 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7906 if (streq(t
, "now"))
7908 else if (!strchr(t
, ':')) {
7911 if (safe_atou64(t
, &u
) < 0)
7914 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7923 hour
= strtol(t
, &e
, 10);
7924 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7927 minute
= strtol(e
+1, &e
, 10);
7928 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7931 n
= now(CLOCK_REALTIME
);
7932 s
= (time_t) (n
/ USEC_PER_SEC
);
7934 assert_se(localtime_r(&s
, &tm
));
7936 tm
.tm_hour
= (int) hour
;
7937 tm
.tm_min
= (int) minute
;
7940 assert_se(s
= mktime(&tm
));
7942 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7945 *_u
+= USEC_PER_DAY
;
7951 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7958 static const struct option options
[] = {
7959 { "help", no_argument
, NULL
, ARG_HELP
},
7960 { "halt", no_argument
, NULL
, 'H' },
7961 { "poweroff", no_argument
, NULL
, 'P' },
7962 { "reboot", no_argument
, NULL
, 'r' },
7963 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7964 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7974 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7982 arg_action
= ACTION_HALT
;
7986 arg_action
= ACTION_POWEROFF
;
7991 arg_action
= ACTION_KEXEC
;
7993 arg_action
= ACTION_REBOOT
;
7997 arg_action
= ACTION_KEXEC
;
8001 if (arg_action
!= ACTION_HALT
)
8002 arg_action
= ACTION_POWEROFF
;
8017 /* Compatibility nops */
8021 arg_action
= ACTION_CANCEL_SHUTDOWN
;
8028 assert_not_reached("Unhandled option");
8031 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
8032 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
8034 log_error("Failed to parse time specification: %s", argv
[optind
]);
8038 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
8040 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
8041 /* No time argument for shutdown cancel */
8042 wall
= argv
+ optind
;
8043 else if (argc
> optind
+ 1)
8044 /* We skip the time argument */
8045 wall
= argv
+ optind
+ 1;
8048 arg_wall
= strv_copy(wall
);
8058 static int telinit_parse_argv(int argc
, char *argv
[]) {
8065 static const struct option options
[] = {
8066 { "help", no_argument
, NULL
, ARG_HELP
},
8067 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
8071 static const struct {
8075 { '0', ACTION_POWEROFF
},
8076 { '6', ACTION_REBOOT
},
8077 { '1', ACTION_RESCUE
},
8078 { '2', ACTION_RUNLEVEL2
},
8079 { '3', ACTION_RUNLEVEL3
},
8080 { '4', ACTION_RUNLEVEL4
},
8081 { '5', ACTION_RUNLEVEL5
},
8082 { 's', ACTION_RESCUE
},
8083 { 'S', ACTION_RESCUE
},
8084 { 'q', ACTION_RELOAD
},
8085 { 'Q', ACTION_RELOAD
},
8086 { 'u', ACTION_REEXEC
},
8087 { 'U', ACTION_REEXEC
}
8096 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
8111 assert_not_reached("Unhandled option");
8114 if (optind
>= argc
) {
8115 log_error("%s: required argument missing.", program_invocation_short_name
);
8119 if (optind
+ 1 < argc
) {
8120 log_error("Too many arguments.");
8124 if (strlen(argv
[optind
]) != 1) {
8125 log_error("Expected single character argument.");
8129 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
8130 if (table
[i
].from
== argv
[optind
][0])
8133 if (i
>= ELEMENTSOF(table
)) {
8134 log_error("Unknown command '%s'.", argv
[optind
]);
8138 arg_action
= table
[i
].to
;
8145 static int runlevel_parse_argv(int argc
, char *argv
[]) {
8151 static const struct option options
[] = {
8152 { "help", no_argument
, NULL
, ARG_HELP
},
8161 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
8172 assert_not_reached("Unhandled option");
8175 if (optind
< argc
) {
8176 log_error("Too many arguments.");
8183 static int parse_argv(int argc
, char *argv
[]) {
8187 if (program_invocation_short_name
) {
8189 if (strstr(program_invocation_short_name
, "halt")) {
8190 arg_action
= ACTION_HALT
;
8191 return halt_parse_argv(argc
, argv
);
8192 } else if (strstr(program_invocation_short_name
, "poweroff")) {
8193 arg_action
= ACTION_POWEROFF
;
8194 return halt_parse_argv(argc
, argv
);
8195 } else if (strstr(program_invocation_short_name
, "reboot")) {
8197 arg_action
= ACTION_KEXEC
;
8199 arg_action
= ACTION_REBOOT
;
8200 return halt_parse_argv(argc
, argv
);
8201 } else if (strstr(program_invocation_short_name
, "shutdown")) {
8202 arg_action
= ACTION_POWEROFF
;
8203 return shutdown_parse_argv(argc
, argv
);
8204 } else if (strstr(program_invocation_short_name
, "init")) {
8206 if (sd_booted() > 0) {
8207 arg_action
= _ACTION_INVALID
;
8208 return telinit_parse_argv(argc
, argv
);
8210 /* Hmm, so some other init system is
8211 * running, we need to forward this
8212 * request to it. For now we simply
8213 * guess that it is Upstart. */
8215 execv(TELINIT
, argv
);
8217 log_error("Couldn't find an alternative telinit implementation to spawn.");
8221 } else if (strstr(program_invocation_short_name
, "runlevel")) {
8222 arg_action
= ACTION_RUNLEVEL
;
8223 return runlevel_parse_argv(argc
, argv
);
8227 arg_action
= ACTION_SYSTEMCTL
;
8228 return systemctl_parse_argv(argc
, argv
);
8231 #if HAVE_SYSV_COMPAT
8232 _pure_
static int action_to_runlevel(void) {
8234 static const char table
[_ACTION_MAX
] = {
8235 [ACTION_HALT
] = '0',
8236 [ACTION_POWEROFF
] = '0',
8237 [ACTION_REBOOT
] = '6',
8238 [ACTION_RUNLEVEL2
] = '2',
8239 [ACTION_RUNLEVEL3
] = '3',
8240 [ACTION_RUNLEVEL4
] = '4',
8241 [ACTION_RUNLEVEL5
] = '5',
8242 [ACTION_RESCUE
] = '1'
8245 assert(arg_action
>= 0 && arg_action
< _ACTION_MAX
);
8247 return table
[arg_action
];
8251 static int talk_initctl(void) {
8252 #if HAVE_SYSV_COMPAT
8253 struct init_request request
= {
8254 .magic
= INIT_MAGIC
,
8256 .cmd
= INIT_CMD_RUNLVL
8259 _cleanup_close_
int fd
= -1;
8263 rl
= action_to_runlevel();
8267 request
.runlevel
= rl
;
8269 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
8271 if (errno
== ENOENT
)
8274 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
8277 r
= loop_write(fd
, &request
, sizeof(request
), false);
8279 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
8287 static int systemctl_main(int argc
, char *argv
[]) {
8289 static const Verb verbs
[] = {
8290 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
8291 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
8292 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
8293 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
8294 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
8295 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
8296 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, trivial_method
},
8297 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
8298 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8299 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8300 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8301 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8302 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8303 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8304 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8305 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
8306 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8307 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
8308 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8309 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
8310 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
8311 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
8312 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8313 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8314 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
8315 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8316 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
8317 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8318 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8319 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8320 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8321 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
8322 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8323 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8324 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
8325 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8326 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8327 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_system_special
},
8328 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8329 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8330 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8331 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8332 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
8333 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8334 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8335 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
8336 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
8337 { "enable", 2, VERB_ANY
, 0, enable_unit
},
8338 { "disable", 2, VERB_ANY
, 0, enable_unit
},
8339 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
8340 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
8341 { "preset", 2, VERB_ANY
, 0, enable_unit
},
8342 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
8343 { "mask", 2, VERB_ANY
, 0, enable_unit
},
8344 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
8345 { "link", 2, VERB_ANY
, 0, enable_unit
},
8346 { "revert", 2, VERB_ANY
, 0, enable_unit
},
8347 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
8348 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
8349 { "set-default", 2, 2, 0, set_default
},
8350 { "get-default", VERB_ANY
, 1, 0, get_default
},
8351 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
8352 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
8353 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
8354 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
8355 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
8359 return dispatch_verb(argc
, argv
, verbs
, NULL
);
8362 static int reload_with_fallback(void) {
8364 /* First, try systemd via D-Bus. */
8365 if (daemon_reload(0, NULL
, NULL
) >= 0)
8368 /* Nothing else worked, so let's try signals */
8369 assert(IN_SET(arg_action
, ACTION_RELOAD
, ACTION_REEXEC
));
8371 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
8372 return log_error_errno(errno
, "kill() failed: %m");
8377 static int start_with_fallback(void) {
8379 /* First, try systemd via D-Bus. */
8380 if (start_unit(0, NULL
, NULL
) >= 0)
8383 /* Nothing else worked, so let's try /dev/initctl */
8384 if (talk_initctl() > 0)
8387 log_error("Failed to talk to init daemon.");
8391 static int halt_now(enum action a
) {
8394 /* The kernel will automaticall flush ATA disks and suchlike
8395 * on reboot(), but the file systems need to be synce'd
8396 * explicitly in advance. */
8400 /* Make sure C-A-D is handled by the kernel from this point
8402 (void) reboot(RB_ENABLE_CAD
);
8408 log_info("Halting.");
8409 (void) reboot(RB_HALT_SYSTEM
);
8412 case ACTION_POWEROFF
:
8414 log_info("Powering off.");
8415 (void) reboot(RB_POWER_OFF
);
8419 case ACTION_REBOOT
: {
8420 _cleanup_free_
char *param
= NULL
;
8422 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
8423 if (r
< 0 && r
!= -ENOENT
)
8424 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
8426 if (!isempty(param
)) {
8428 log_info("Rebooting with argument '%s'.", param
);
8429 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
8430 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
8434 log_info("Rebooting.");
8435 (void) reboot(RB_AUTOBOOT
);
8440 assert_not_reached("Unknown action.");
8444 static int logind_schedule_shutdown(void) {
8447 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8448 char date
[FORMAT_TIMESTAMP_MAX
];
8453 r
= acquire_bus(BUS_FULL
, &bus
);
8457 switch (arg_action
) {
8461 case ACTION_POWEROFF
:
8462 action
= "poweroff";
8477 action
= strjoina("dry-", action
);
8479 (void) logind_set_wall_message();
8481 r
= sd_bus_call_method(
8483 "org.freedesktop.login1",
8484 "/org/freedesktop/login1",
8485 "org.freedesktop.login1.Manager",
8493 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
8496 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
8499 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8504 static int halt_main(void) {
8507 r
= logind_check_inhibitors(arg_action
);
8512 return logind_schedule_shutdown();
8514 if (geteuid() != 0) {
8515 if (arg_dry
|| arg_force
> 0) {
8516 log_error("Must be root.");
8520 /* Try logind if we are a normal user and no special
8521 * mode applies. Maybe PolicyKit allows us to shutdown
8523 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
, ACTION_HALT
)) {
8524 r
= logind_reboot(arg_action
);
8527 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
8528 /* requested operation is not
8529 * supported on the local system or
8530 * already in progress */
8532 /* on all other errors, try low-level operation */
8536 if (!arg_dry
&& !arg_force
)
8537 return start_with_fallback();
8539 assert(geteuid() == 0);
8542 if (sd_booted() > 0)
8543 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8545 r
= utmp_put_shutdown();
8547 log_warning_errno(r
, "Failed to write utmp record: %m");
8554 r
= halt_now(arg_action
);
8555 return log_error_errno(r
, "Failed to reboot: %m");
8558 static int runlevel_main(void) {
8559 int r
, runlevel
, previous
;
8561 r
= utmp_get_runlevel(&runlevel
, &previous
);
8568 previous
<= 0 ? 'N' : previous
,
8569 runlevel
<= 0 ? 'N' : runlevel
);
8574 static int logind_cancel_shutdown(void) {
8576 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8580 r
= acquire_bus(BUS_FULL
, &bus
);
8584 (void) logind_set_wall_message();
8586 r
= sd_bus_call_method(
8588 "org.freedesktop.login1",
8589 "/org/freedesktop/login1",
8590 "org.freedesktop.login1.Manager",
8591 "CancelScheduledShutdown",
8595 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
8599 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8604 int main(int argc
, char*argv
[]) {
8607 argv_cmdline
= argv
[0];
8609 setlocale(LC_ALL
, "");
8610 log_parse_environment();
8614 /* Explicitly not on_tty() to avoid setting cached value.
8615 * This becomes relevant for piping output which might be
8617 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
8619 r
= parse_argv(argc
, argv
);
8623 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
8626 log_info("Running in chroot, ignoring request.");
8631 /* systemctl_main() will print an error message for the bus
8632 * connection, but only if it needs to */
8634 switch (arg_action
) {
8636 case ACTION_SYSTEMCTL
:
8637 r
= systemctl_main(argc
, argv
);
8640 /* Legacy command aliases set arg_action. They provide some fallbacks,
8641 * e.g. to tell sysvinit to reboot after you have installed systemd
8645 case ACTION_POWEROFF
:
8651 case ACTION_RUNLEVEL2
:
8652 case ACTION_RUNLEVEL3
:
8653 case ACTION_RUNLEVEL4
:
8654 case ACTION_RUNLEVEL5
:
8656 r
= start_with_fallback();
8661 r
= reload_with_fallback();
8664 case ACTION_CANCEL_SHUTDOWN
:
8665 r
= logind_cancel_shutdown();
8668 case ACTION_RUNLEVEL
:
8669 r
= runlevel_main();
8673 case ACTION_SUSPEND
:
8674 case ACTION_HIBERNATE
:
8675 case ACTION_HYBRID_SLEEP
:
8676 case ACTION_EMERGENCY
:
8677 case ACTION_DEFAULT
:
8678 /* systemctl verbs with no equivalent in the legacy commands.
8679 * These cannot appear in arg_action. Fall through. */
8681 case _ACTION_INVALID
:
8683 assert_not_reached("Unknown action");
8690 ask_password_agent_close();
8691 polkit_agent_close();
8693 strv_free(arg_types
);
8694 strv_free(arg_states
);
8695 strv_free(arg_properties
);
8697 strv_free(arg_wall
);
8700 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8701 return r
< 0 ? EXIT_FAILURE
: r
;