2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Marc-Antoine Perennou
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/reboot.h>
30 #include <sys/reboot.h>
31 #include <sys/socket.h>
35 #include "sd-daemon.h"
38 #include "alloc-util.h"
39 #include "bus-common-errors.h"
40 #include "bus-error.h"
41 #include "bus-message.h"
42 #include "bus-unit-util.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
50 #include "exit-status.h"
53 #include "formats-util.h"
55 #include "glob-util.h"
56 #include "hostname-util.h"
61 #include "locale-util.h"
63 #include "logs-show.h"
67 #include "parse-util.h"
68 #include "path-lookup.h"
69 #include "path-util.h"
70 #include "process-util.h"
71 #include "rlimit-util.h"
74 #include "signal-util.h"
75 #include "socket-util.h"
76 #include "spawn-ask-password-agent.h"
77 #include "spawn-polkit-agent.h"
79 #include "stat-util.h"
81 #include "terminal-util.h"
82 #include "unit-name.h"
83 #include "user-util.h"
85 #include "utmp-wtmp.h"
89 /* The init script exit status codes
90 0 program is running or service is OK
91 1 program is dead and /var/run pid file exists
92 2 program is dead and /var/lock lock file exists
93 3 program is not running
94 4 program or service status is unknown
95 5-99 reserved for future LSB use
96 100-149 reserved for distribution use
97 150-199 reserved for application use
101 EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
= 0,
102 EXIT_PROGRAM_DEAD_AND_PID_EXISTS
= 1,
103 EXIT_PROGRAM_DEAD_AND_LOCK_FILE_EXISTS
= 2,
104 EXIT_PROGRAM_NOT_RUNNING
= 3,
105 EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
= 4,
108 static char **arg_types
= NULL
;
109 static char **arg_states
= NULL
;
110 static char **arg_properties
= NULL
;
111 static bool arg_all
= false;
112 static enum dependency
{
118 } arg_dependency
= DEPENDENCY_FORWARD
;
119 static const char *arg_job_mode
= "replace";
120 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
121 static bool arg_wait
= false;
122 static bool arg_no_block
= false;
123 static bool arg_no_legend
= false;
124 static bool arg_no_pager
= false;
125 static bool arg_no_wtmp
= false;
126 static bool arg_no_sync
= false;
127 static bool arg_no_wall
= false;
128 static bool arg_no_reload
= false;
129 static bool arg_value
= false;
130 static bool arg_show_types
= false;
131 static bool arg_ignore_inhibitors
= false;
132 static bool arg_dry
= false;
133 static bool arg_quiet
= false;
134 static bool arg_full
= false;
135 static bool arg_recursive
= false;
136 static int arg_force
= 0;
137 static bool arg_ask_password
= false;
138 static bool arg_runtime
= false;
139 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
140 static char **arg_wall
= NULL
;
141 static const char *arg_kill_who
= NULL
;
142 static int arg_signal
= SIGTERM
;
143 static char *arg_root
= NULL
;
144 static usec_t arg_when
= 0;
166 ACTION_CANCEL_SHUTDOWN
,
168 } arg_action
= ACTION_SYSTEMCTL
;
169 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
170 static const char *arg_host
= NULL
;
171 static unsigned arg_lines
= 10;
172 static OutputMode arg_output
= OUTPUT_SHORT
;
173 static bool arg_plain
= false;
174 static bool arg_firmware_setup
= false;
175 static bool arg_now
= false;
177 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
178 static int trivial_method(int argc
, char *argv
[], void *userdata
);
179 static int halt_now(enum action a
);
180 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
182 static bool original_stdout_is_tty
;
184 typedef enum BusFocus
{
185 BUS_FULL
, /* The full bus indicated via --system or --user */
186 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
190 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
192 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
195 assert(focus
< _BUS_FOCUS_MAX
);
198 /* We only go directly to the manager, if we are using a local transport */
199 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
202 if (!busses
[focus
]) {
205 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
207 if (focus
== BUS_MANAGER
)
208 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
210 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
212 return log_error_errno(r
, "Failed to connect to bus: %m");
214 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
217 *ret
= busses
[focus
];
221 static void release_busses(void) {
224 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
225 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
228 static int map_string_no_copy(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
230 const char **p
= userdata
;
233 r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &s
);
243 static void ask_password_agent_open_if_enabled(void) {
245 /* Open the password agent as a child process if necessary */
247 if (!arg_ask_password
)
250 if (arg_scope
!= UNIT_FILE_SYSTEM
)
253 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
256 ask_password_agent_open();
259 static void polkit_agent_open_if_enabled(void) {
261 /* Open the polkit agent as a child process if necessary */
263 if (!arg_ask_password
)
266 if (arg_scope
!= UNIT_FILE_SYSTEM
)
269 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
275 static OutputFlags
get_output_flags(void) {
277 arg_all
* OUTPUT_SHOW_ALL
|
278 arg_full
* OUTPUT_FULL_WIDTH
|
279 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
280 colors_enabled() * OUTPUT_COLOR
|
281 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
284 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
287 if (!sd_bus_error_is_set(error
))
290 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
291 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
292 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
293 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
294 return EXIT_NOPERMISSION
;
296 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
297 return EXIT_NOTINSTALLED
;
299 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
300 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
301 return EXIT_NOTIMPLEMENTED
;
303 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
304 return EXIT_NOTCONFIGURED
;
312 static bool install_client_side(void) {
314 /* Decides when to execute enable/disable/... operations
315 * client-side rather than server-side. */
317 if (running_in_chroot() > 0)
320 if (sd_booted() <= 0)
323 if (!isempty(arg_root
))
326 if (arg_scope
== UNIT_FILE_GLOBAL
)
329 /* Unsupported environment variable, mostly for debugging purposes */
330 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
336 static int compare_unit_info(const void *a
, const void *b
) {
337 const UnitInfo
*u
= a
, *v
= b
;
341 /* First, order by machine */
342 if (!u
->machine
&& v
->machine
)
344 if (u
->machine
&& !v
->machine
)
346 if (u
->machine
&& v
->machine
) {
347 r
= strcasecmp(u
->machine
, v
->machine
);
352 /* Second, order by unit type */
353 d1
= strrchr(u
->id
, '.');
354 d2
= strrchr(v
->id
, '.');
356 r
= strcasecmp(d1
, d2
);
361 /* Third, order by name */
362 return strcasecmp(u
->id
, v
->id
);
365 static const char* unit_type_suffix(const char *name
) {
368 dot
= strrchr(name
, '.');
375 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
378 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
381 if (arg_types
&& !strv_find(arg_types
, unit_type_suffix(u
->id
)))
387 /* Note that '--all' is not purely a state filter, but also a
388 * filter that hides units that "follow" other units (which is
389 * used for device units that appear under different names). */
390 if (!isempty(u
->following
))
393 if (!strv_isempty(arg_states
))
396 /* By default show all units except the ones in inactive
397 * state and with no pending job */
401 if (streq(u
->active_state
, "inactive"))
407 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
408 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
;
410 unsigned n_shown
= 0;
411 int job_count
= 0, desc_len
;
413 max_id_len
= strlen("UNIT");
414 load_len
= strlen("LOAD");
415 active_len
= strlen("ACTIVE");
416 sub_len
= strlen("SUB");
417 job_len
= strlen("JOB");
420 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
421 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
422 load_len
= MAX(load_len
, strlen(u
->load_state
));
423 active_len
= MAX(active_len
, strlen(u
->active_state
));
424 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
426 if (u
->job_id
!= 0) {
427 job_len
= MAX(job_len
, strlen(u
->job_type
));
431 if (!arg_no_legend
&&
432 (streq(u
->active_state
, "failed") ||
433 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
437 if (!arg_full
&& original_stdout_is_tty
) {
440 id_len
= MIN(max_id_len
, 25u);
441 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
444 basic_len
+= job_len
+ 1;
446 if (basic_len
< (unsigned) columns()) {
447 unsigned extra_len
, incr
;
448 extra_len
= columns() - basic_len
;
450 /* Either UNIT already got 25, or is fully satisfied.
451 * Grant up to 25 to DESC now. */
452 incr
= MIN(extra_len
, 25u);
456 /* split the remaining space between UNIT and DESC,
457 * but do not give UNIT more than it needs. */
459 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
461 desc_len
+= extra_len
- incr
;
467 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
468 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
469 const char *on_underline
= "", *off_underline
= "";
470 const char *on_loaded
= "", *off_loaded
= "";
471 const char *on_active
= "", *off_active
= "";
472 const char *on_circle
= "", *off_circle
= "";
474 bool circle
= false, underline
= false;
476 if (!n_shown
&& !arg_no_legend
) {
481 printf("%s%-*s %-*s %-*s %-*s ",
485 active_len
, "ACTIVE",
489 printf("%-*s ", job_len
, "JOB");
492 !arg_full
&& arg_no_pager
? desc_len
: -1,
499 if (u
+ 1 < unit_infos
+ c
&&
500 !streq(unit_type_suffix(u
->id
), unit_type_suffix((u
+ 1)->id
))) {
501 on_underline
= ansi_underline();
502 off_underline
= ansi_normal();
506 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
507 on_circle
= ansi_highlight_yellow();
508 off_circle
= ansi_normal();
510 on_loaded
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
511 off_loaded
= on_underline
;
512 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
513 on_circle
= ansi_highlight_red();
514 off_circle
= ansi_normal();
516 on_active
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
517 off_active
= on_underline
;
521 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
530 e
= ellipsize(id
, id_len
, 33);
538 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
540 printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
542 on_active
, id_len
, id
, off_active
,
543 on_loaded
, load_len
, u
->load_state
, off_loaded
,
544 on_active
, active_len
, u
->active_state
,
545 sub_len
, u
->sub_state
, off_active
,
546 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
549 desc_len
> 0 ? desc_len
: -1,
554 if (!arg_no_legend
) {
555 const char *on
, *off
;
559 "LOAD = Reflects whether the unit definition was properly loaded.\n"
560 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
561 "SUB = The low-level unit activation state, values depend on unit type.");
562 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
563 on
= ansi_highlight();
566 on
= ansi_highlight_red();
571 printf("%s%u loaded units listed.%s\n"
572 "To show all installed unit files use 'systemctl list-unit-files'.\n",
575 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
576 "To show all installed unit files use 'systemctl list-unit-files'.\n",
583 static int get_unit_list(
587 UnitInfo
**unit_infos
,
589 sd_bus_message
**_reply
) {
591 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
592 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
593 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
597 bool fallback
= false;
603 r
= sd_bus_message_new_method_call(
606 "org.freedesktop.systemd1",
607 "/org/freedesktop/systemd1",
608 "org.freedesktop.systemd1.Manager",
609 "ListUnitsByPatterns");
611 return bus_log_create_error(r
);
613 r
= sd_bus_message_append_strv(m
, arg_states
);
615 return bus_log_create_error(r
);
617 r
= sd_bus_message_append_strv(m
, patterns
);
619 return bus_log_create_error(r
);
621 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
622 if (r
< 0 && (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
) ||
623 sd_bus_error_has_name(&error
, SD_BUS_ERROR_ACCESS_DENIED
))) {
624 /* Fallback to legacy ListUnitsFiltered method */
626 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
627 m
= sd_bus_message_unref(m
);
628 sd_bus_error_free(&error
);
630 r
= sd_bus_message_new_method_call(
633 "org.freedesktop.systemd1",
634 "/org/freedesktop/systemd1",
635 "org.freedesktop.systemd1.Manager",
636 "ListUnitsFiltered");
638 return bus_log_create_error(r
);
640 r
= sd_bus_message_append_strv(m
, arg_states
);
642 return bus_log_create_error(r
);
644 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
647 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
649 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
651 return bus_log_parse_error(r
);
653 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
656 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
659 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
662 (*unit_infos
)[c
++] = u
;
665 return bus_log_parse_error(r
);
667 r
= sd_bus_message_exit_container(reply
);
669 return bus_log_parse_error(r
);
677 static void message_set_freep(Set
**set
) {
680 while ((m
= set_steal_first(*set
)))
681 sd_bus_message_unref(m
);
686 static int get_unit_list_recursive(
689 UnitInfo
**_unit_infos
,
693 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
694 _cleanup_(message_set_freep
) Set
*replies
;
695 sd_bus_message
*reply
;
703 replies
= set_new(NULL
);
707 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
711 r
= set_put(replies
, reply
);
713 sd_bus_message_unref(reply
);
718 _cleanup_strv_free_
char **machines
= NULL
;
721 r
= sd_get_machine_names(&machines
);
723 return log_error_errno(r
, "Failed to get machine names: %m");
725 STRV_FOREACH(i
, machines
) {
726 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
729 r
= sd_bus_open_system_machine(&container
, *i
);
731 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
735 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
741 r
= set_put(replies
, reply
);
743 sd_bus_message_unref(reply
);
748 *_machines
= machines
;
753 *_unit_infos
= unit_infos
;
762 static int list_units(int argc
, char *argv
[], void *userdata
) {
763 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
764 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
765 _cleanup_strv_free_
char **machines
= NULL
;
769 r
= acquire_bus(BUS_MANAGER
, &bus
);
773 pager_open(arg_no_pager
, false);
775 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
779 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
780 return output_units_list(unit_infos
, r
);
783 static int get_triggered_units(
788 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
795 r
= sd_bus_get_property_strv(
797 "org.freedesktop.systemd1",
799 "org.freedesktop.systemd1.Unit",
804 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
809 static int get_listening(
811 const char* unit_path
,
814 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
815 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
816 const char *type
, *path
;
819 r
= sd_bus_get_property(
821 "org.freedesktop.systemd1",
823 "org.freedesktop.systemd1.Socket",
829 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
831 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
833 return bus_log_parse_error(r
);
835 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
837 r
= strv_extend(listening
, type
);
841 r
= strv_extend(listening
, path
);
848 return bus_log_parse_error(r
);
850 r
= sd_bus_message_exit_container(reply
);
852 return bus_log_parse_error(r
);
864 /* Note: triggered is a list here, although it almost certainly
865 * will always be one unit. Nevertheless, dbus API allows for multiple
866 * values, so let's follow that. */
869 /* The strv above is shared. free is set only in the first one. */
873 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
879 if (!a
->machine
&& b
->machine
)
881 if (a
->machine
&& !b
->machine
)
883 if (a
->machine
&& b
->machine
) {
884 o
= strcasecmp(a
->machine
, b
->machine
);
889 o
= strcmp(a
->path
, b
->path
);
891 o
= strcmp(a
->type
, b
->type
);
896 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
897 struct socket_info
*s
;
898 unsigned pathlen
= strlen("LISTEN"),
899 typelen
= strlen("TYPE") * arg_show_types
,
900 socklen
= strlen("UNIT"),
901 servlen
= strlen("ACTIVATES");
902 const char *on
, *off
;
904 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
908 socklen
= MAX(socklen
, strlen(s
->id
));
910 typelen
= MAX(typelen
, strlen(s
->type
));
911 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
913 STRV_FOREACH(a
, s
->triggered
)
914 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
915 servlen
= MAX(servlen
, tmp
);
920 printf("%-*s %-*.*s%-*s %s\n",
922 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
926 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
927 _cleanup_free_
char *j
= NULL
;
932 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
940 printf("%-*s %-*s %-*s",
941 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
944 pathlen
, path
, socklen
, s
->id
);
945 STRV_FOREACH(a
, s
->triggered
)
947 a
== s
->triggered
? "" : ",", *a
);
951 on
= ansi_highlight();
956 on
= ansi_highlight_red();
960 if (!arg_no_legend
) {
961 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
963 printf("Pass --all to see loaded but inactive sockets, too.\n");
969 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
970 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
971 _cleanup_strv_free_
char **machines
= NULL
;
972 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
973 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
975 struct socket_info
*s
;
981 r
= acquire_bus(BUS_MANAGER
, &bus
);
985 pager_open(arg_no_pager
, false);
987 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
991 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
992 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
995 if (!endswith(u
->id
, ".socket"))
998 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1002 c
= get_listening(bus
, u
->unit_path
, &listening
);
1008 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
1013 for (i
= 0; i
< c
; i
++)
1014 socket_infos
[cs
+ i
] = (struct socket_info
) {
1015 .machine
= u
->machine
,
1017 .type
= listening
[i
*2],
1018 .path
= listening
[i
*2 + 1],
1019 .triggered
= triggered
,
1020 .own_triggered
= i
==0,
1023 /* from this point on we will cleanup those socket_infos */
1026 listening
= triggered
= NULL
; /* avoid cleanup */
1029 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
1030 (__compar_fn_t
) socket_info_compare
);
1032 output_sockets_list(socket_infos
, cs
);
1035 assert(cs
== 0 || socket_infos
);
1036 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
1039 if (s
->own_triggered
)
1040 strv_free(s
->triggered
);
1046 static int get_next_elapse(
1049 dual_timestamp
*next
) {
1051 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1059 r
= sd_bus_get_property_trivial(
1061 "org.freedesktop.systemd1",
1063 "org.freedesktop.systemd1.Timer",
1064 "NextElapseUSecMonotonic",
1069 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1071 r
= sd_bus_get_property_trivial(
1073 "org.freedesktop.systemd1",
1075 "org.freedesktop.systemd1.Timer",
1076 "NextElapseUSecRealtime",
1081 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1087 static int get_last_trigger(
1092 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1099 r
= sd_bus_get_property_trivial(
1101 "org.freedesktop.systemd1",
1103 "org.freedesktop.systemd1.Timer",
1109 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1115 const char* machine
;
1118 usec_t last_trigger
;
1122 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1128 if (!a
->machine
&& b
->machine
)
1130 if (a
->machine
&& !b
->machine
)
1132 if (a
->machine
&& b
->machine
) {
1133 o
= strcasecmp(a
->machine
, b
->machine
);
1138 if (a
->next_elapse
< b
->next_elapse
)
1140 if (a
->next_elapse
> b
->next_elapse
)
1143 return strcmp(a
->id
, b
->id
);
1146 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1147 struct timer_info
*t
;
1149 nextlen
= strlen("NEXT"),
1150 leftlen
= strlen("LEFT"),
1151 lastlen
= strlen("LAST"),
1152 passedlen
= strlen("PASSED"),
1153 unitlen
= strlen("UNIT"),
1154 activatelen
= strlen("ACTIVATES");
1156 const char *on
, *off
;
1158 assert(timer_infos
|| n
== 0);
1160 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1164 if (t
->next_elapse
> 0) {
1165 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1167 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1168 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1170 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1171 leftlen
= MAX(leftlen
, strlen(trel
));
1174 if (t
->last_trigger
> 0) {
1175 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1177 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1178 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1180 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1181 passedlen
= MAX(passedlen
, strlen(trel
));
1184 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1186 STRV_FOREACH(a
, t
->triggered
)
1187 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1189 activatelen
= MAX(activatelen
, ul
);
1194 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1198 passedlen
, "PASSED",
1202 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1203 _cleanup_free_
char *j
= NULL
;
1205 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1206 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1209 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1210 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1212 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1213 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1216 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1223 printf("%-*s %-*s %-*s %-*s %-*s",
1224 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1226 STRV_FOREACH(a
, t
->triggered
)
1228 a
== t
->triggered
? "" : ",", *a
);
1232 on
= ansi_highlight();
1233 off
= ansi_normal();
1237 on
= ansi_highlight_red();
1238 off
= ansi_normal();
1241 if (!arg_no_legend
) {
1242 printf("%s%u timers listed.%s\n", on
, n
, off
);
1244 printf("Pass --all to see loaded but inactive timers, too.\n");
1250 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1256 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1259 if (next
->monotonic
> nw
->monotonic
)
1260 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1262 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1264 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1265 next_elapse
= MIN(converted
, next
->realtime
);
1267 next_elapse
= converted
;
1270 next_elapse
= next
->realtime
;
1275 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1276 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1277 _cleanup_strv_free_
char **machines
= NULL
;
1278 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1279 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1280 struct timer_info
*t
;
1288 r
= acquire_bus(BUS_MANAGER
, &bus
);
1292 pager_open(arg_no_pager
, false);
1294 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1298 dual_timestamp_get(&nw
);
1300 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1301 _cleanup_strv_free_
char **triggered
= NULL
;
1302 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1305 if (!endswith(u
->id
, ".timer"))
1308 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1312 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1316 get_last_trigger(bus
, u
->unit_path
, &last
);
1318 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1323 m
= calc_next_elapse(&nw
, &next
);
1325 timer_infos
[c
++] = (struct timer_info
) {
1326 .machine
= u
->machine
,
1329 .last_trigger
= last
,
1330 .triggered
= triggered
,
1333 triggered
= NULL
; /* avoid cleanup */
1336 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1337 (__compar_fn_t
) timer_info_compare
);
1339 output_timers_list(timer_infos
, c
);
1342 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1343 strv_free(t
->triggered
);
1348 static int compare_unit_file_list(const void *a
, const void *b
) {
1349 const char *d1
, *d2
;
1350 const UnitFileList
*u
= a
, *v
= b
;
1352 d1
= strrchr(u
->path
, '.');
1353 d2
= strrchr(v
->path
, '.');
1358 r
= strcasecmp(d1
, d2
);
1363 return strcasecmp(basename(u
->path
), basename(v
->path
));
1366 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1369 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1372 if (!strv_isempty(arg_types
)) {
1375 dot
= strrchr(u
->path
, '.');
1379 if (!strv_find(arg_types
, dot
+1))
1383 if (!strv_isempty(states
) &&
1384 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1390 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1391 unsigned max_id_len
, id_cols
, state_cols
;
1392 const UnitFileList
*u
;
1394 max_id_len
= strlen("UNIT FILE");
1395 state_cols
= strlen("STATE");
1397 for (u
= units
; u
< units
+ c
; u
++) {
1398 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1399 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1403 unsigned basic_cols
;
1405 id_cols
= MIN(max_id_len
, 25u);
1406 basic_cols
= 1 + id_cols
+ state_cols
;
1407 if (basic_cols
< (unsigned) columns())
1408 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1410 id_cols
= max_id_len
;
1412 if (!arg_no_legend
&& c
> 0)
1413 printf("%s%-*s %-*s%s\n",
1415 id_cols
, "UNIT FILE",
1416 state_cols
, "STATE",
1419 for (u
= units
; u
< units
+ c
; u
++) {
1420 _cleanup_free_
char *e
= NULL
;
1421 const char *on
, *off
, *on_underline
= "", *off_underline
= "";
1423 bool underline
= false;
1425 if (u
+ 1 < units
+ c
&&
1426 !streq(unit_type_suffix(u
->path
), unit_type_suffix((u
+ 1)->path
))) {
1427 on_underline
= ansi_underline();
1428 off_underline
= ansi_normal();
1432 if (IN_SET(u
->state
,
1434 UNIT_FILE_MASKED_RUNTIME
,
1437 on
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
1438 else if (u
->state
== UNIT_FILE_ENABLED
)
1439 on
= underline
? ansi_highlight_green_underline() : ansi_highlight_green();
1442 off
= off_underline
;
1444 id
= basename(u
->path
);
1446 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1448 printf("%s%-*s %s%-*s%s%s\n",
1450 id_cols
, e
? e
: id
,
1451 on
, state_cols
, unit_file_state_to_string(u
->state
), off
,
1456 printf("\n%u unit files listed.\n", c
);
1459 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1460 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1461 _cleanup_free_ UnitFileList
*units
= NULL
;
1468 bool fallback
= false;
1470 if (install_client_side()) {
1476 h
= hashmap_new(&string_hash_ops
);
1480 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1482 unit_file_list_free(h
);
1483 return log_error_errno(r
, "Failed to get unit file list: %m");
1486 n_units
= hashmap_size(h
);
1488 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1490 unit_file_list_free(h
);
1494 HASHMAP_FOREACH(u
, h
, i
) {
1495 if (!output_show_unit_file(u
, NULL
, NULL
))
1502 assert(c
<= n_units
);
1507 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1508 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1511 r
= acquire_bus(BUS_MANAGER
, &bus
);
1515 r
= sd_bus_message_new_method_call(
1518 "org.freedesktop.systemd1",
1519 "/org/freedesktop/systemd1",
1520 "org.freedesktop.systemd1.Manager",
1521 "ListUnitFilesByPatterns");
1523 return bus_log_create_error(r
);
1525 r
= sd_bus_message_append_strv(m
, arg_states
);
1527 return bus_log_create_error(r
);
1529 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1531 return bus_log_create_error(r
);
1533 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1534 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1535 /* Fallback to legacy ListUnitFiles method */
1537 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1538 m
= sd_bus_message_unref(m
);
1539 sd_bus_error_free(&error
);
1541 r
= sd_bus_message_new_method_call(
1544 "org.freedesktop.systemd1",
1545 "/org/freedesktop/systemd1",
1546 "org.freedesktop.systemd1.Manager",
1549 return bus_log_create_error(r
);
1551 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1554 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1556 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1558 return bus_log_parse_error(r
);
1560 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1562 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1565 units
[c
] = (struct UnitFileList
) {
1567 unit_file_state_from_string(state
)
1570 if (output_show_unit_file(&units
[c
],
1571 fallback
? arg_states
: NULL
,
1572 fallback
? strv_skip(argv
, 1) : NULL
))
1577 return bus_log_parse_error(r
);
1579 r
= sd_bus_message_exit_container(reply
);
1581 return bus_log_parse_error(r
);
1584 pager_open(arg_no_pager
, false);
1586 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1587 output_unit_file_list(units
, c
);
1589 if (install_client_side())
1590 for (unit
= units
; unit
< units
+ c
; unit
++)
1596 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1597 _cleanup_free_
char *n
= NULL
;
1598 size_t max_len
= MAX(columns(),20u);
1604 for (i
= level
- 1; i
>= 0; i
--) {
1606 if (len
> max_len
- 3 && !arg_full
) {
1607 printf("%s...\n",max_len
% 2 ? "" : " ");
1610 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1614 if (len
> max_len
- 3 && !arg_full
) {
1615 printf("%s...\n",max_len
% 2 ? "" : " ");
1619 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1623 printf("%s\n", name
);
1627 n
= ellipsize(name
, max_len
-len
, 100);
1635 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1637 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1638 [DEPENDENCY_FORWARD
] = "Requires\0"
1643 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1648 [DEPENDENCY_AFTER
] = "After\0",
1649 [DEPENDENCY_BEFORE
] = "Before\0",
1652 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1653 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1654 _cleanup_strv_free_
char **ret
= NULL
;
1655 _cleanup_free_
char *path
= NULL
;
1661 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1663 path
= unit_dbus_path_from_name(name
);
1667 r
= sd_bus_call_method(
1669 "org.freedesktop.systemd1",
1671 "org.freedesktop.DBus.Properties",
1675 "s", "org.freedesktop.systemd1.Unit");
1677 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1679 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1681 return bus_log_parse_error(r
);
1683 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1686 r
= sd_bus_message_read(reply
, "s", &prop
);
1688 return bus_log_parse_error(r
);
1690 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1691 r
= sd_bus_message_skip(reply
, "v");
1693 return bus_log_parse_error(r
);
1696 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1698 return bus_log_parse_error(r
);
1700 r
= bus_message_read_strv_extend(reply
, &ret
);
1702 return bus_log_parse_error(r
);
1704 r
= sd_bus_message_exit_container(reply
);
1706 return bus_log_parse_error(r
);
1709 r
= sd_bus_message_exit_container(reply
);
1711 return bus_log_parse_error(r
);
1715 return bus_log_parse_error(r
);
1717 r
= sd_bus_message_exit_container(reply
);
1719 return bus_log_parse_error(r
);
1727 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1728 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1730 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1732 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1735 return strcasecmp(*a
, *b
);
1738 static int list_dependencies_one(
1743 unsigned int branches
) {
1745 _cleanup_strv_free_
char **deps
= NULL
;
1753 r
= strv_extend(units
, name
);
1757 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1761 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1763 STRV_FOREACH(c
, deps
) {
1764 if (strv_contains(*units
, *c
)) {
1766 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1776 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1779 (void) get_state_one_unit(bus
, *c
, &active_state
);
1781 switch (active_state
) {
1783 case UNIT_RELOADING
:
1784 case UNIT_ACTIVATING
:
1785 on
= ansi_highlight_green();
1789 case UNIT_DEACTIVATING
:
1794 on
= ansi_highlight_red();
1798 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1801 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1805 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1806 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1813 strv_remove(*units
, name
);
1818 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1819 _cleanup_strv_free_
char **units
= NULL
;
1820 _cleanup_free_
char *unit
= NULL
;
1826 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1828 return log_error_errno(r
, "Failed to mangle unit name: %m");
1832 u
= SPECIAL_DEFAULT_TARGET
;
1834 r
= acquire_bus(BUS_MANAGER
, &bus
);
1838 pager_open(arg_no_pager
, false);
1842 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1845 struct machine_info
{
1849 char *control_group
;
1850 uint32_t n_failed_units
;
1855 static const struct bus_properties_map machine_info_property_map
[] = {
1856 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1857 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1858 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1859 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1860 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1864 static void machine_info_clear(struct machine_info
*info
) {
1869 free(info
->control_group
);
1873 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1879 for (i
= 0; i
< n
; i
++)
1880 machine_info_clear(&machine_infos
[i
]);
1882 free(machine_infos
);
1885 static int compare_machine_info(const void *a
, const void *b
) {
1886 const struct machine_info
*u
= a
, *v
= b
;
1888 if (u
->is_host
!= v
->is_host
)
1889 return u
->is_host
> v
->is_host
? -1 : 1;
1891 return strcasecmp(u
->name
, v
->name
);
1894 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1895 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1901 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1908 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1915 static bool output_show_machine(const char *name
, char **patterns
) {
1916 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1919 static int get_machine_list(
1921 struct machine_info
**_machine_infos
,
1924 struct machine_info
*machine_infos
= NULL
;
1925 _cleanup_strv_free_
char **m
= NULL
;
1926 _cleanup_free_
char *hn
= NULL
;
1931 hn
= gethostname_malloc();
1935 if (output_show_machine(hn
, patterns
)) {
1936 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1939 machine_infos
[c
].is_host
= true;
1940 machine_infos
[c
].name
= hn
;
1943 get_machine_properties(bus
, &machine_infos
[c
]);
1947 r
= sd_get_machine_names(&m
);
1949 return log_error_errno(r
, "Failed to get machine list: %m");
1951 STRV_FOREACH(i
, m
) {
1952 _cleanup_free_
char *class = NULL
;
1954 if (!output_show_machine(*i
, patterns
))
1957 sd_machine_get_class(*i
, &class);
1958 if (!streq_ptr(class, "container"))
1961 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1962 free_machines_list(machine_infos
, c
);
1966 machine_infos
[c
].is_host
= false;
1967 machine_infos
[c
].name
= strdup(*i
);
1968 if (!machine_infos
[c
].name
) {
1969 free_machines_list(machine_infos
, c
);
1973 get_machine_properties(NULL
, &machine_infos
[c
]);
1977 *_machine_infos
= machine_infos
;
1981 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1982 struct machine_info
*m
;
1985 namelen
= sizeof("NAME") - 1,
1986 statelen
= sizeof("STATE") - 1,
1987 failedlen
= sizeof("FAILED") - 1,
1988 jobslen
= sizeof("JOBS") - 1;
1990 assert(machine_infos
|| n
== 0);
1992 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1993 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1994 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1995 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1996 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1998 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
2002 if (!arg_no_legend
) {
2006 printf("%-*s %-*s %-*s %-*s\n",
2009 failedlen
, "FAILED",
2013 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2014 const char *on_state
= "", *off_state
= "";
2015 const char *on_failed
= "", *off_failed
= "";
2016 bool circle
= false;
2018 if (streq_ptr(m
->state
, "degraded")) {
2019 on_state
= ansi_highlight_red();
2020 off_state
= ansi_normal();
2022 } else if (!streq_ptr(m
->state
, "running")) {
2023 on_state
= ansi_highlight_yellow();
2024 off_state
= ansi_normal();
2028 if (m
->n_failed_units
> 0) {
2029 on_failed
= ansi_highlight_red();
2030 off_failed
= ansi_normal();
2032 on_failed
= off_failed
= "";
2035 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
2038 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2039 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
2040 on_state
, statelen
, strna(m
->state
), off_state
,
2041 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2042 jobslen
, m
->n_jobs
);
2044 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2045 namelen
, strna(m
->name
),
2046 on_state
, statelen
, strna(m
->state
), off_state
,
2047 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2048 jobslen
, m
->n_jobs
);
2052 printf("\n%u machines listed.\n", n
);
2055 static int list_machines(int argc
, char *argv
[], void *userdata
) {
2056 struct machine_info
*machine_infos
= NULL
;
2060 if (geteuid() != 0) {
2061 log_error("Must be root.");
2065 r
= acquire_bus(BUS_MANAGER
, &bus
);
2069 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2073 pager_open(arg_no_pager
, false);
2075 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2076 output_machines_list(machine_infos
, r
);
2077 free_machines_list(machine_infos
, r
);
2082 static int get_default(int argc
, char *argv
[], void *userdata
) {
2083 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2084 _cleanup_free_
char *_path
= NULL
;
2088 if (install_client_side()) {
2089 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2091 return log_error_errno(r
, "Failed to get default target: %m");
2096 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2099 r
= acquire_bus(BUS_MANAGER
, &bus
);
2103 r
= sd_bus_call_method(
2105 "org.freedesktop.systemd1",
2106 "/org/freedesktop/systemd1",
2107 "org.freedesktop.systemd1.Manager",
2113 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2115 r
= sd_bus_message_read(reply
, "s", &path
);
2117 return bus_log_parse_error(r
);
2121 printf("%s\n", path
);
2126 static int set_default(int argc
, char *argv
[], void *userdata
) {
2127 _cleanup_free_
char *unit
= NULL
;
2128 UnitFileChange
*changes
= NULL
;
2129 unsigned n_changes
= 0;
2135 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2137 return log_error_errno(r
, "Failed to mangle unit name: %m");
2139 if (install_client_side()) {
2140 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2141 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2146 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2147 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2150 polkit_agent_open_if_enabled();
2152 r
= acquire_bus(BUS_MANAGER
, &bus
);
2156 r
= sd_bus_call_method(
2158 "org.freedesktop.systemd1",
2159 "/org/freedesktop/systemd1",
2160 "org.freedesktop.systemd1.Manager",
2166 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2168 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2172 /* Try to reload if enabled */
2174 r
= daemon_reload(argc
, argv
, userdata
);
2180 unit_file_changes_free(changes
, n_changes
);
2187 const char *name
, *type
, *state
;
2190 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2191 unsigned id_len
, unit_len
, type_len
, state_len
;
2192 const struct job_info
*j
;
2193 const char *on
, *off
;
2194 bool shorten
= false;
2196 assert(n
== 0 || jobs
);
2199 if (!arg_no_legend
) {
2200 on
= ansi_highlight_green();
2201 off
= ansi_normal();
2203 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2208 pager_open(arg_no_pager
, false);
2210 id_len
= strlen("JOB");
2211 unit_len
= strlen("UNIT");
2212 type_len
= strlen("TYPE");
2213 state_len
= strlen("STATE");
2215 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2216 uint32_t id
= j
->id
;
2217 assert(j
->name
&& j
->type
&& j
->state
);
2219 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2220 unit_len
= MAX(unit_len
, strlen(j
->name
));
2221 type_len
= MAX(type_len
, strlen(j
->type
));
2222 state_len
= MAX(state_len
, strlen(j
->state
));
2225 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2226 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2231 printf("%*s %-*s %-*s %-*s\n",
2235 state_len
, "STATE");
2237 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2238 _cleanup_free_
char *e
= NULL
;
2240 if (streq(j
->state
, "running")) {
2241 on
= ansi_highlight();
2242 off
= ansi_normal();
2246 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2247 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2249 on
, unit_len
, e
? e
: j
->name
, off
,
2251 on
, state_len
, j
->state
, off
);
2254 if (!arg_no_legend
) {
2255 on
= ansi_highlight();
2256 off
= ansi_normal();
2258 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2262 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2263 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2266 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2267 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2268 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2269 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2270 _cleanup_free_
struct job_info
*jobs
= NULL
;
2276 bool skipped
= false;
2278 r
= acquire_bus(BUS_MANAGER
, &bus
);
2282 r
= sd_bus_call_method(
2284 "org.freedesktop.systemd1",
2285 "/org/freedesktop/systemd1",
2286 "org.freedesktop.systemd1.Manager",
2292 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2294 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2296 return bus_log_parse_error(r
);
2298 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2299 struct job_info job
= { id
, name
, type
, state
};
2301 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2306 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2312 return bus_log_parse_error(r
);
2314 r
= sd_bus_message_exit_container(reply
);
2316 return bus_log_parse_error(r
);
2318 pager_open(arg_no_pager
, false);
2320 output_jobs_list(jobs
, c
, skipped
);
2324 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2330 return trivial_method(argc
, argv
, userdata
);
2332 r
= acquire_bus(BUS_MANAGER
, &bus
);
2336 polkit_agent_open_if_enabled();
2338 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2339 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2343 q
= safe_atou32(*name
, &id
);
2345 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2347 q
= sd_bus_call_method(
2349 "org.freedesktop.systemd1",
2350 "/org/freedesktop/systemd1",
2351 "org.freedesktop.systemd1.Manager",
2357 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2366 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2367 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2371 /* We ignore all errors here, since this is used to show a
2374 /* We don't use unit_dbus_path_from_name() directly since we
2375 * don't want to load the unit if it isn't loaded. */
2377 r
= sd_bus_call_method(
2379 "org.freedesktop.systemd1",
2380 "/org/freedesktop/systemd1",
2381 "org.freedesktop.systemd1.Manager",
2389 r
= sd_bus_message_read(reply
, "o", &path
);
2393 r
= sd_bus_get_property_trivial(
2395 "org.freedesktop.systemd1",
2397 "org.freedesktop.systemd1.Unit",
2407 static void warn_unit_file_changed(const char *name
) {
2410 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2411 ansi_highlight_red(),
2414 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2417 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2424 STRV_FOREACH(p
, lp
->search_path
) {
2425 _cleanup_free_
char *path
;
2427 path
= path_join(arg_root
, *p
, unit_name
);
2431 if (access(path
, F_OK
) == 0) {
2441 static int unit_find_paths(
2443 const char *unit_name
,
2445 char **fragment_path
,
2446 char ***dropin_paths
) {
2448 _cleanup_free_
char *path
= NULL
;
2449 _cleanup_strv_free_
char **dropins
= NULL
;
2453 * Finds where the unit is defined on disk. Returns 0 if the unit
2454 * is not found. Returns 1 if it is found, and sets
2455 * - the path to the unit in *path, if it exists on disk,
2456 * - and a strv of existing drop-ins in *dropins,
2457 * if the arg is not NULL and any dropins were found.
2461 assert(fragment_path
);
2464 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2465 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2466 _cleanup_free_
char *unit
= NULL
;
2468 unit
= unit_dbus_path_from_name(unit_name
);
2472 r
= sd_bus_get_property_string(
2474 "org.freedesktop.systemd1",
2476 "org.freedesktop.systemd1.Unit",
2481 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2484 r
= sd_bus_get_property_strv(
2486 "org.freedesktop.systemd1",
2488 "org.freedesktop.systemd1.Unit",
2493 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2496 _cleanup_set_free_ Set
*names
;
2498 names
= set_new(NULL
);
2502 r
= set_put(names
, unit_name
);
2504 return log_error_errno(r
, "Failed to add unit name: %m");
2506 r
= unit_file_find_path(lp
, unit_name
, &path
);
2511 _cleanup_free_
char *template = NULL
;
2513 r
= unit_name_template(unit_name
, &template);
2514 if (r
< 0 && r
!= -EINVAL
)
2515 return log_error_errno(r
, "Failed to determine template name: %m");
2517 r
= unit_file_find_path(lp
, template, &path
);
2524 r
= unit_file_find_dropin_paths(lp
->search_path
, NULL
, names
, &dropins
);
2532 if (!isempty(path
)) {
2533 *fragment_path
= path
;
2538 if (dropin_paths
&& !strv_isempty(dropins
)) {
2539 *dropin_paths
= dropins
;
2544 if (r
== 0 && !arg_force
)
2545 log_error("No files found for %s.", unit_name
);
2550 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2551 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2552 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2553 _cleanup_free_
char *buf
= NULL
;
2554 UnitActiveState state
;
2559 assert(active_state
);
2561 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2563 r
= sd_bus_call_method(
2565 "org.freedesktop.systemd1",
2566 "/org/freedesktop/systemd1",
2567 "org.freedesktop.systemd1.Manager",
2573 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2574 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2576 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2577 * considered inactive. */
2578 state
= UNIT_INACTIVE
;
2581 r
= sd_bus_message_read(reply
, "o", &path
);
2583 return bus_log_parse_error(r
);
2585 r
= sd_bus_get_property_string(
2587 "org.freedesktop.systemd1",
2589 "org.freedesktop.systemd1.Unit",
2594 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2596 state
= unit_active_state_from_string(buf
);
2597 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2598 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2603 *active_state
= state
;
2607 static int check_triggering_units(
2611 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2612 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2613 _cleanup_strv_free_
char **triggered_by
= NULL
;
2614 bool print_warning_label
= true;
2615 UnitActiveState active_state
;
2619 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2621 return log_error_errno(r
, "Failed to mangle unit name: %m");
2623 path
= unit_dbus_path_from_name(n
);
2627 r
= sd_bus_get_property_string(
2629 "org.freedesktop.systemd1",
2631 "org.freedesktop.systemd1.Unit",
2636 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2638 if (streq(load_state
, "masked"))
2641 r
= sd_bus_get_property_strv(
2643 "org.freedesktop.systemd1",
2645 "org.freedesktop.systemd1.Unit",
2650 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2652 STRV_FOREACH(i
, triggered_by
) {
2653 r
= get_state_one_unit(bus
, *i
, &active_state
);
2657 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2660 if (print_warning_label
) {
2661 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2662 print_warning_label
= false;
2665 log_warning(" %s", *i
);
2671 static const struct {
2674 } unit_actions
[] = {
2675 { "start", "StartUnit" },
2676 { "stop", "StopUnit" },
2677 { "condstop", "StopUnit" },
2678 { "reload", "ReloadUnit" },
2679 { "restart", "RestartUnit" },
2680 { "try-restart", "TryRestartUnit" },
2681 { "condrestart", "TryRestartUnit" },
2682 { "reload-or-restart", "ReloadOrRestartUnit" },
2683 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2684 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2685 { "condreload", "ReloadOrTryRestartUnit" },
2686 { "force-reload", "ReloadOrTryRestartUnit" }
2689 static const char *verb_to_method(const char *verb
) {
2692 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2693 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2694 return unit_actions
[i
].method
;
2699 static const char *method_to_verb(const char *method
) {
2702 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2703 if (streq_ptr(unit_actions
[i
].method
, method
))
2704 return unit_actions
[i
].verb
;
2716 static void wait_context_free(WaitContext
*c
) {
2717 c
->match
= sd_bus_slot_unref(c
->match
);
2718 c
->event
= sd_event_unref(c
->event
);
2719 c
->unit_paths
= set_free(c
->unit_paths
);
2722 static int on_properties_changed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
2723 WaitContext
*c
= userdata
;
2727 path
= sd_bus_message_get_path(m
);
2728 if (!set_contains(c
->unit_paths
, path
))
2731 /* Check if ActiveState changed to inactive/failed */
2732 /* (s interface, a{sv} changed_properties, as invalidated_properties) */
2733 r
= sd_bus_message_skip(m
, "s");
2735 return bus_log_parse_error(r
);
2736 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
2738 return bus_log_parse_error(r
);
2740 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
2744 r
= sd_bus_message_read(m
, "s", &s
);
2746 return bus_log_parse_error(r
);
2747 if (streq(s
, "ActiveState")) {
2748 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, "s");
2750 return bus_log_parse_error(r
);
2751 r
= sd_bus_message_read(m
, "s", &s
);
2753 return bus_log_parse_error(r
);
2754 is_failed
= streq(s
, "failed");
2755 if (streq(s
, "inactive") || is_failed
) {
2756 log_debug("%s became %s, dropping from --wait tracking", path
, s
);
2757 set_remove(c
->unit_paths
, path
);
2758 c
->any_failed
|= is_failed
;
2760 log_debug("ActiveState on %s changed to %s", path
, s
);
2761 break; /* no need to dissect the rest of the message */
2763 /* other property */
2764 r
= sd_bus_message_skip(m
, "v");
2766 return bus_log_parse_error(r
);
2768 r
= sd_bus_message_exit_container(m
);
2770 return bus_log_parse_error(r
);
2773 return bus_log_parse_error(r
);
2775 if (set_isempty(c
->unit_paths
))
2776 sd_event_exit(c
->event
, EXIT_SUCCESS
);
2781 static int start_unit_one(
2786 sd_bus_error
*error
,
2788 WaitContext
*wait_context
) {
2790 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2800 _cleanup_free_
char *unit_path
= NULL
;
2803 log_debug("Watching for property changes of %s", name
);
2804 r
= sd_bus_call_method(
2806 "org.freedesktop.systemd1",
2807 "/org/freedesktop/systemd1",
2808 "org.freedesktop.systemd1.Manager",
2814 return log_error_errno(r
, "Failed to RefUnit %s: %s", name
, bus_error_message(error
, r
));
2816 unit_path
= unit_dbus_path_from_name(name
);
2820 r
= set_put_strdup(wait_context
->unit_paths
, unit_path
);
2822 return log_error_errno(r
, "Failed to add unit path %s to set: %m", unit_path
);
2824 mt
= strjoina("type='signal',"
2825 "interface='org.freedesktop.DBus.Properties',"
2826 "path='", unit_path
, "',"
2827 "member='PropertiesChanged'");
2828 r
= sd_bus_add_match(bus
, &wait_context
->match
, mt
, on_properties_changed
, wait_context
);
2830 return log_error_errno(r
, "Failed to add match for PropertiesChanged signal: %m");
2833 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2835 r
= sd_bus_call_method(
2837 "org.freedesktop.systemd1",
2838 "/org/freedesktop/systemd1",
2839 "org.freedesktop.systemd1.Manager",
2847 /* There's always a fallback possible for legacy actions. */
2848 if (arg_action
!= ACTION_SYSTEMCTL
)
2851 verb
= method_to_verb(method
);
2853 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2855 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2856 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2857 log_error("See %s logs and 'systemctl%s status%s %s' for details.",
2858 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2859 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2860 name
[0] == '-' ? " --" : "",
2866 r
= sd_bus_message_read(reply
, "o", &path
);
2868 return bus_log_parse_error(r
);
2870 if (need_daemon_reload(bus
, name
) > 0)
2871 warn_unit_file_changed(name
);
2874 log_debug("Adding %s to the set", path
);
2875 r
= bus_wait_for_jobs_add(w
, path
);
2883 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2884 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2891 STRV_FOREACH(name
, names
) {
2895 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2897 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2899 return log_error_errno(r
, "Failed to mangle name: %m");
2901 if (string_is_glob(t
))
2902 r
= strv_consume(&globs
, t
);
2904 r
= strv_consume(&mangled
, t
);
2909 /* Query the manager only if any of the names are a glob, since
2910 * this is fairly expensive */
2911 if (!strv_isempty(globs
)) {
2912 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2913 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2914 size_t allocated
, n
;
2916 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2920 n
= strv_length(mangled
);
2923 for (i
= 0; i
< r
; i
++) {
2924 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2927 mangled
[n
] = strdup(unit_infos
[i
].id
);
2931 mangled
[++n
] = NULL
;
2936 mangled
= NULL
; /* do not free */
2941 static const struct {
2945 } action_table
[_ACTION_MAX
] = {
2946 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2947 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2948 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2949 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2950 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2951 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2952 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2953 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2954 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2955 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2956 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2957 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2958 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2959 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2960 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2963 static enum action
verb_to_action(const char *verb
) {
2966 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2967 if (streq_ptr(action_table
[i
].verb
, verb
))
2970 return _ACTION_INVALID
;
2973 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2974 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2975 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2976 _cleanup_strv_free_
char **names
= NULL
;
2978 _cleanup_(wait_context_free
) WaitContext wait_context
= {};
2982 if (arg_wait
&& !strstr(argv
[0], "start")) {
2983 log_error("--wait may only be used with a command that starts units.");
2987 /* we cannot do sender tracking on the private bus, so we need the full
2988 * one for RefUnit to implement --wait */
2989 r
= acquire_bus(arg_wait
? BUS_FULL
: BUS_MANAGER
, &bus
);
2993 ask_password_agent_open_if_enabled();
2994 polkit_agent_open_if_enabled();
2996 if (arg_action
== ACTION_SYSTEMCTL
) {
2999 method
= verb_to_method(argv
[0]);
3000 action
= verb_to_action(argv
[0]);
3002 if (streq(argv
[0], "isolate")) {
3006 mode
= action_table
[action
].mode
?: arg_job_mode
;
3008 one_name
= action_table
[action
].target
;
3010 assert(arg_action
< ELEMENTSOF(action_table
));
3011 assert(action_table
[arg_action
].target
);
3013 method
= "StartUnit";
3015 mode
= action_table
[arg_action
].mode
;
3016 one_name
= action_table
[arg_action
].target
;
3020 names
= strv_new(one_name
, NULL
);
3022 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
3024 return log_error_errno(r
, "Failed to expand names: %m");
3027 if (!arg_no_block
) {
3028 r
= bus_wait_for_jobs_new(bus
, &w
);
3030 return log_error_errno(r
, "Could not watch jobs: %m");
3034 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3036 wait_context
.unit_paths
= set_new(&string_hash_ops
);
3037 if (!wait_context
.unit_paths
)
3040 r
= sd_bus_call_method(
3042 "org.freedesktop.systemd1",
3043 "/org/freedesktop/systemd1",
3044 "org.freedesktop.systemd1.Manager",
3049 return log_error_errno(r
, "Failed to enable subscription: %s", bus_error_message(&error
, r
));
3050 r
= sd_event_default(&wait_context
.event
);
3052 return log_error_errno(r
, "Failed to allocate event loop: %m");
3053 r
= sd_bus_attach_event(bus
, wait_context
.event
, 0);
3055 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
3058 STRV_FOREACH(name
, names
) {
3059 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3062 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
, arg_wait
? &wait_context
: NULL
);
3063 if (r
>= 0 && q
< 0)
3064 r
= translate_bus_error_to_exit_status(q
, &error
);
3067 if (!arg_no_block
) {
3068 int q
, arg_count
= 0;
3069 const char* extra_args
[4] = {};
3071 if (arg_scope
!= UNIT_FILE_SYSTEM
)
3072 extra_args
[arg_count
++] = "--user";
3074 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
3075 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
3076 extra_args
[arg_count
++] = "-H";
3077 extra_args
[arg_count
++] = arg_host
;
3078 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
3079 extra_args
[arg_count
++] = "-M";
3080 extra_args
[arg_count
++] = arg_host
;
3083 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
3087 /* When stopping units, warn if they can still be triggered by
3088 * another active unit (socket, path, timer) */
3089 if (!arg_quiet
&& streq(method
, "StopUnit"))
3090 STRV_FOREACH(name
, names
)
3091 check_triggering_units(bus
, *name
);
3094 if (r
>= 0 && arg_wait
) {
3096 q
= sd_event_loop(wait_context
.event
);
3098 return log_error_errno(q
, "Failed to run event loop: %m");
3099 if (wait_context
.any_failed
)
3106 static int logind_set_wall_message(void) {
3108 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3110 _cleanup_free_
char *m
= NULL
;
3113 r
= acquire_bus(BUS_FULL
, &bus
);
3117 m
= strv_join(arg_wall
, " ");
3121 r
= sd_bus_call_method(
3123 "org.freedesktop.login1",
3124 "/org/freedesktop/login1",
3125 "org.freedesktop.login1.Manager",
3134 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
3140 /* Ask systemd-logind, which might grant access to unprivileged users
3141 * through PolicyKit */
3142 static int logind_reboot(enum action a
) {
3144 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3145 const char *method
, *description
;
3149 r
= acquire_bus(BUS_FULL
, &bus
);
3157 description
= "reboot system";
3160 case ACTION_POWEROFF
:
3161 method
= "PowerOff";
3162 description
= "power off system";
3165 case ACTION_SUSPEND
:
3167 description
= "suspend system";
3170 case ACTION_HIBERNATE
:
3171 method
= "Hibernate";
3172 description
= "hibernate system";
3175 case ACTION_HYBRID_SLEEP
:
3176 method
= "HybridSleep";
3177 description
= "put system into hybrid sleep";
3184 polkit_agent_open_if_enabled();
3185 (void) logind_set_wall_message();
3187 r
= sd_bus_call_method(
3189 "org.freedesktop.login1",
3190 "/org/freedesktop/login1",
3191 "org.freedesktop.login1.Manager",
3195 "b", arg_ask_password
);
3197 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
3205 static int logind_check_inhibitors(enum action a
) {
3207 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3208 _cleanup_strv_free_
char **sessions
= NULL
;
3209 const char *what
, *who
, *why
, *mode
;
3216 if (arg_ignore_inhibitors
|| arg_force
> 0)
3228 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
3231 r
= acquire_bus(BUS_FULL
, &bus
);
3235 r
= sd_bus_call_method(
3237 "org.freedesktop.login1",
3238 "/org/freedesktop/login1",
3239 "org.freedesktop.login1.Manager",
3245 /* If logind is not around, then there are no inhibitors... */
3248 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3250 return bus_log_parse_error(r
);
3252 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3253 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3254 _cleanup_strv_free_
char **sv
= NULL
;
3256 if (!streq(mode
, "block"))
3259 sv
= strv_split(what
, ":");
3263 if ((pid_t
) pid
< 0)
3264 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
3266 if (!strv_contains(sv
,
3271 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3274 get_process_comm(pid
, &comm
);
3275 user
= uid_to_name(uid
);
3277 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3278 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3283 return bus_log_parse_error(r
);
3285 r
= sd_bus_message_exit_container(reply
);
3287 return bus_log_parse_error(r
);
3289 /* Check for current sessions */
3290 sd_get_sessions(&sessions
);
3291 STRV_FOREACH(s
, sessions
) {
3292 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3294 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3297 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3300 if (sd_session_get_type(*s
, &type
) < 0 || !STR_IN_SET(type
, "x11", "tty"))
3303 sd_session_get_tty(*s
, &tty
);
3304 sd_session_get_seat(*s
, &seat
);
3305 sd_session_get_service(*s
, &service
);
3306 user
= uid_to_name(uid
);
3308 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3315 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3316 action_table
[a
].verb
);
3324 static int logind_prepare_firmware_setup(void) {
3326 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3330 r
= acquire_bus(BUS_FULL
, &bus
);
3334 r
= sd_bus_call_method(
3336 "org.freedesktop.login1",
3337 "/org/freedesktop/login1",
3338 "org.freedesktop.login1.Manager",
3339 "SetRebootToFirmwareSetup",
3344 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3348 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3353 static int prepare_firmware_setup(void) {
3356 if (!arg_firmware_setup
)
3359 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3361 r
= efi_set_reboot_to_firmware(true);
3363 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3368 return logind_prepare_firmware_setup();
3371 static int set_exit_code(uint8_t code
) {
3372 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3376 r
= acquire_bus(BUS_MANAGER
, &bus
);
3380 r
= sd_bus_call_method(
3382 "org.freedesktop.systemd1",
3383 "/org/freedesktop/systemd1",
3384 "org.freedesktop.systemd1.Manager",
3390 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3395 static int start_special(int argc
, char *argv
[], void *userdata
) {
3401 a
= verb_to_action(argv
[0]);
3403 r
= logind_check_inhibitors(a
);
3407 if (arg_force
>= 2 && geteuid() != 0) {
3408 log_error("Must be root.");
3412 r
= prepare_firmware_setup();
3416 if (a
== ACTION_REBOOT
&& argc
> 1) {
3417 r
= update_reboot_parameter_and_warn(argv
[1]);
3421 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3424 /* If the exit code is not given on the command line,
3425 * don't reset it to zero: just keep it as it might
3426 * have been set previously. */
3428 r
= safe_atou8(argv
[1], &code
);
3430 return log_error_errno(r
, "Invalid exit code.");
3432 r
= set_exit_code(code
);
3437 if (arg_force
>= 2 &&
3444 if (arg_force
>= 1 &&
3451 return trivial_method(argc
, argv
, userdata
);
3453 /* First try logind, to allow authentication with polkit */
3459 ACTION_HYBRID_SLEEP
)) {
3460 r
= logind_reboot(a
);
3463 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3464 /* requested operation is not supported or already in progress */
3467 /* On all other errors, try low-level operation */
3470 return start_unit(argc
, argv
, userdata
);
3473 static int start_system_special(int argc
, char *argv
[], void *userdata
) {
3474 /* Like start_special above, but raises an error when running in user mode */
3476 if (arg_scope
!= UNIT_FILE_SYSTEM
) {
3477 log_error("Bad action for %s mode.",
3478 arg_scope
== UNIT_FILE_GLOBAL
? "--global" : "--user");
3482 return start_special(argc
, argv
, userdata
);
3485 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3486 _cleanup_strv_free_
char **names
= NULL
;
3487 UnitActiveState active_state
;
3493 r
= acquire_bus(BUS_MANAGER
, &bus
);
3497 r
= expand_names(bus
, args
, NULL
, &names
);
3499 return log_error_errno(r
, "Failed to expand names: %m");
3501 STRV_FOREACH(name
, names
) {
3502 r
= get_state_one_unit(bus
, *name
, &active_state
);
3507 puts(unit_active_state_to_string(active_state
));
3509 for (i
= 0; i
< nb_states
; ++i
)
3510 if (good_states
[i
] == active_state
)
3514 /* use the given return code for the case that we won't find
3515 * any unit which matches the list */
3516 return found
? 0 : code
;
3519 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3520 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3521 /* According to LSB: 3, "program is not running" */
3522 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3525 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3526 const UnitActiveState states
[] = { UNIT_FAILED
};
3527 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3530 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3531 _cleanup_strv_free_
char **names
= NULL
;
3532 char *kill_who
= NULL
, **name
;
3536 r
= acquire_bus(BUS_MANAGER
, &bus
);
3540 polkit_agent_open_if_enabled();
3543 arg_kill_who
= "all";
3545 /* --fail was specified */
3546 if (streq(arg_job_mode
, "fail"))
3547 kill_who
= strjoina(arg_kill_who
, "-fail");
3549 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3551 return log_error_errno(r
, "Failed to expand names: %m");
3553 STRV_FOREACH(name
, names
) {
3554 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3556 q
= sd_bus_call_method(
3558 "org.freedesktop.systemd1",
3559 "/org/freedesktop/systemd1",
3560 "org.freedesktop.systemd1.Manager",
3564 "ssi", *name
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3566 log_error_errno(q
, "Failed to kill unit %s: %s", *name
, bus_error_message(&error
, q
));
3575 typedef struct ExecStatusInfo
{
3583 usec_t start_timestamp
;
3584 usec_t exit_timestamp
;
3589 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3592 static void exec_status_info_free(ExecStatusInfo
*i
) {
3601 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3602 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3605 int32_t code
, status
;
3611 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3613 return bus_log_parse_error(r
);
3617 r
= sd_bus_message_read(m
, "s", &path
);
3619 return bus_log_parse_error(r
);
3621 i
->path
= strdup(path
);
3625 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3627 return bus_log_parse_error(r
);
3629 r
= sd_bus_message_read(m
,
3632 &start_timestamp
, &start_timestamp_monotonic
,
3633 &exit_timestamp
, &exit_timestamp_monotonic
,
3637 return bus_log_parse_error(r
);
3640 i
->start_timestamp
= (usec_t
) start_timestamp
;
3641 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3642 i
->pid
= (pid_t
) pid
;
3646 r
= sd_bus_message_exit_container(m
);
3648 return bus_log_parse_error(r
);
3653 typedef struct UnitCondition
{
3660 LIST_FIELDS(struct UnitCondition
, conditions
);
3663 static void unit_condition_free(UnitCondition
*c
) {
3672 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition
*, unit_condition_free
);
3674 typedef struct UnitStatusInfo
{
3676 const char *load_state
;
3677 const char *active_state
;
3678 const char *sub_state
;
3679 const char *unit_file_state
;
3680 const char *unit_file_preset
;
3682 const char *description
;
3683 const char *following
;
3685 char **documentation
;
3687 const char *fragment_path
;
3688 const char *source_path
;
3689 const char *control_group
;
3691 char **dropin_paths
;
3693 const char *load_error
;
3696 usec_t inactive_exit_timestamp
;
3697 usec_t inactive_exit_timestamp_monotonic
;
3698 usec_t active_enter_timestamp
;
3699 usec_t active_exit_timestamp
;
3700 usec_t inactive_enter_timestamp
;
3702 bool need_daemon_reload
;
3708 const char *status_text
;
3709 const char *pid_file
;
3713 usec_t start_timestamp
;
3714 usec_t exit_timestamp
;
3716 int exit_code
, exit_status
;
3718 usec_t condition_timestamp
;
3719 bool condition_result
;
3720 LIST_HEAD(UnitCondition
, conditions
);
3722 usec_t assert_timestamp
;
3724 bool failed_assert_trigger
;
3725 bool failed_assert_negate
;
3726 const char *failed_assert
;
3727 const char *failed_assert_parameter
;
3730 unsigned n_accepted
;
3731 unsigned n_connections
;
3734 /* Pairs of type, path */
3738 const char *sysfs_path
;
3740 /* Mount, Automount */
3747 uint64_t memory_current
;
3748 uint64_t memory_low
;
3749 uint64_t memory_high
;
3750 uint64_t memory_max
;
3751 uint64_t memory_swap_max
;
3752 uint64_t memory_limit
;
3753 uint64_t cpu_usage_nsec
;
3754 uint64_t tasks_current
;
3757 LIST_HEAD(ExecStatusInfo
, exec
);
3760 static void unit_status_info_free(UnitStatusInfo
*info
) {
3764 strv_free(info
->documentation
);
3765 strv_free(info
->dropin_paths
);
3766 strv_free(info
->listen
);
3768 while ((c
= info
->conditions
)) {
3769 LIST_REMOVE(conditions
, info
->conditions
, c
);
3770 unit_condition_free(c
);
3773 while ((p
= info
->exec
)) {
3774 LIST_REMOVE(exec
, info
->exec
, p
);
3775 exec_status_info_free(p
);
3779 static void print_status_info(
3785 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3787 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3788 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3795 /* This shows pretty information about a unit. See
3796 * print_property() for a low-level property printer */
3798 if (streq_ptr(i
->active_state
, "failed")) {
3799 active_on
= ansi_highlight_red();
3800 active_off
= ansi_normal();
3801 } else if (STRPTR_IN_SET(i
->active_state
, "active", "reloading")) {
3802 active_on
= ansi_highlight_green();
3803 active_off
= ansi_normal();
3805 active_on
= active_off
= "";
3807 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3809 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3810 printf(" - %s", i
->description
);
3815 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3817 if (streq_ptr(i
->load_state
, "error")) {
3818 on
= ansi_highlight_red();
3819 off
= ansi_normal();
3823 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3825 if (i
->load_error
!= 0)
3826 printf(" Loaded: %s%s%s (Reason: %s)\n",
3827 on
, strna(i
->load_state
), off
, i
->load_error
);
3828 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3829 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3830 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3831 else if (path
&& !isempty(i
->unit_file_state
))
3832 printf(" Loaded: %s%s%s (%s; %s)\n",
3833 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3835 printf(" Loaded: %s%s%s (%s)\n",
3836 on
, strna(i
->load_state
), off
, path
);
3838 printf(" Loaded: %s%s%s\n",
3839 on
, strna(i
->load_state
), off
);
3842 printf("Transient: yes\n");
3844 if (!strv_isempty(i
->dropin_paths
)) {
3845 _cleanup_free_
char *dir
= NULL
;
3849 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3850 if (! dir
|| last
) {
3851 printf(dir
? " " : " Drop-In: ");
3855 dir
= dirname_malloc(*dropin
);
3861 printf("%s\n %s", dir
,
3862 special_glyph(TREE_RIGHT
));
3865 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3867 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3871 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3873 printf(" Active: %s%s (%s)%s",
3874 active_on
, strna(i
->active_state
), ss
, active_off
);
3876 printf(" Active: %s%s%s",
3877 active_on
, strna(i
->active_state
), active_off
);
3879 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3880 printf(" (Result: %s)", i
->result
);
3882 timestamp
= STRPTR_IN_SET(i
->active_state
, "active", "reloading") ? i
->active_enter_timestamp
:
3883 STRPTR_IN_SET(i
->active_state
, "inactive", "failed") ? i
->inactive_enter_timestamp
:
3884 STRPTR_IN_SET(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3885 i
->active_exit_timestamp
;
3887 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3888 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3891 printf(" since %s; %s\n", s2
, s1
);
3893 printf(" since %s\n", s2
);
3897 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3901 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3902 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3904 printf("Condition: start %scondition failed%s at %s%s%s\n",
3905 ansi_highlight_yellow(), ansi_normal(),
3906 s2
, s1
? "; " : "", strempty(s1
));
3908 LIST_FOREACH(conditions
, c
, i
->conditions
)
3909 if (c
->tristate
< 0)
3912 LIST_FOREACH(conditions
, c
, i
->conditions
)
3913 if (c
->tristate
< 0)
3914 printf(" %s %s=%s%s%s was not met\n",
3915 --n
? special_glyph(TREE_BRANCH
) : special_glyph(TREE_RIGHT
),
3917 c
->trigger
? "|" : "",
3918 c
->negate
? "!" : "",
3922 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3923 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3924 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3926 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3927 ansi_highlight_red(), ansi_normal(),
3928 s2
, s1
? "; " : "", strempty(s1
));
3929 if (i
->failed_assert_trigger
)
3930 printf(" none of the trigger assertions were met\n");
3931 else if (i
->failed_assert
)
3932 printf(" %s=%s%s was not met\n",
3934 i
->failed_assert_negate
? "!" : "",
3935 i
->failed_assert_parameter
);
3939 printf(" Device: %s\n", i
->sysfs_path
);
3941 printf(" Where: %s\n", i
->where
);
3943 printf(" What: %s\n", i
->what
);
3945 STRV_FOREACH(t
, i
->documentation
)
3946 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3948 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3949 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3952 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3954 LIST_FOREACH(exec
, p
, i
->exec
) {
3955 _cleanup_free_
char *argv
= NULL
;
3958 /* Only show exited processes here */
3962 argv
= strv_join(p
->argv
, " ");
3963 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3965 good
= is_clean_exit(p
->code
, p
->status
, EXIT_CLEAN_DAEMON
, NULL
);
3967 on
= ansi_highlight_red();
3968 off
= ansi_normal();
3972 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3974 if (p
->code
== CLD_EXITED
) {
3977 printf("status=%i", p
->status
);
3979 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3984 printf("signal=%s", signal_to_string(p
->status
));
3986 printf(")%s\n", off
);
3988 if (i
->main_pid
== p
->pid
&&
3989 i
->start_timestamp
== p
->start_timestamp
&&
3990 i
->exit_timestamp
== p
->start_timestamp
)
3991 /* Let's not show this twice */
3994 if (p
->pid
== i
->control_pid
)
3998 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3999 if (i
->main_pid
> 0) {
4000 printf(" Main PID: "PID_FMT
, i
->main_pid
);
4003 _cleanup_free_
char *comm
= NULL
;
4004 (void) get_process_comm(i
->main_pid
, &comm
);
4006 printf(" (%s)", comm
);
4007 } else if (i
->exit_code
> 0) {
4008 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
4010 if (i
->exit_code
== CLD_EXITED
) {
4013 printf("status=%i", i
->exit_status
);
4015 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
4020 printf("signal=%s", signal_to_string(i
->exit_status
));
4025 if (i
->control_pid
> 0) {
4026 _cleanup_free_
char *c
= NULL
;
4028 if (i
->main_pid
> 0)
4029 fputs("; Control PID: ", stdout
);
4031 fputs("Cntrl PID: ", stdout
); /* if first in column, abbreviated so it fits alignment */
4033 printf(PID_FMT
, i
->control_pid
);
4035 (void) get_process_comm(i
->control_pid
, &c
);
4044 printf(" Status: \"%s\"\n", i
->status_text
);
4045 if (i
->status_errno
> 0)
4046 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
4048 if (i
->tasks_current
!= (uint64_t) -1) {
4049 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
4051 if (i
->tasks_max
!= (uint64_t) -1)
4052 printf(" (limit: %" PRIu64
")\n", i
->tasks_max
);
4057 if (i
->memory_current
!= (uint64_t) -1) {
4058 char buf
[FORMAT_BYTES_MAX
];
4060 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
4062 if (i
->memory_low
> 0 || i
->memory_high
!= CGROUP_LIMIT_MAX
||
4063 i
->memory_max
!= CGROUP_LIMIT_MAX
|| i
->memory_swap_max
!= CGROUP_LIMIT_MAX
||
4064 i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4065 const char *prefix
= "";
4068 if (i
->memory_low
> 0) {
4069 printf("%slow: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_low
));
4072 if (i
->memory_high
!= CGROUP_LIMIT_MAX
) {
4073 printf("%shigh: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_high
));
4076 if (i
->memory_max
!= CGROUP_LIMIT_MAX
) {
4077 printf("%smax: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_max
));
4080 if (i
->memory_swap_max
!= CGROUP_LIMIT_MAX
) {
4081 printf("%sswap max: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_swap_max
));
4084 if (i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4085 printf("%slimit: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
4093 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
4094 char buf
[FORMAT_TIMESPAN_MAX
];
4095 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
4098 if (i
->control_group
) {
4099 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4100 static const char prefix
[] = " ";
4103 printf(" CGroup: %s\n", i
->control_group
);
4106 if (c
> sizeof(prefix
) - 1)
4107 c
-= sizeof(prefix
) - 1;
4111 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
4116 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4118 if (i
->main_pid
> 0)
4119 extra
[k
++] = i
->main_pid
;
4121 if (i
->control_pid
> 0)
4122 extra
[k
++] = i
->control_pid
;
4124 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
4126 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
4129 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
4130 show_journal_by_unit(
4135 i
->inactive_exit_timestamp_monotonic
,
4138 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
4139 SD_JOURNAL_LOCAL_ONLY
,
4140 arg_scope
== UNIT_FILE_SYSTEM
,
4143 if (i
->need_daemon_reload
)
4144 warn_unit_file_changed(i
->id
);
4147 static void show_unit_help(UnitStatusInfo
*i
) {
4152 if (!i
->documentation
) {
4153 log_info("Documentation for %s not known.", i
->id
);
4157 STRV_FOREACH(p
, i
->documentation
)
4158 if (startswith(*p
, "man:"))
4159 show_man_page(*p
+ 4, false);
4161 log_info("Can't show: %s", *p
);
4164 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
4171 switch (contents
[0]) {
4173 case SD_BUS_TYPE_STRING
: {
4176 r
= sd_bus_message_read(m
, "s", &s
);
4178 return bus_log_parse_error(r
);
4181 if (streq(name
, "Id"))
4183 else if (streq(name
, "LoadState"))
4185 else if (streq(name
, "ActiveState"))
4186 i
->active_state
= s
;
4187 else if (streq(name
, "SubState"))
4189 else if (streq(name
, "Description"))
4191 else if (streq(name
, "FragmentPath"))
4192 i
->fragment_path
= s
;
4193 else if (streq(name
, "SourcePath"))
4196 else if (streq(name
, "DefaultControlGroup")) {
4198 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
4200 i
->control_group
= e
;
4203 else if (streq(name
, "ControlGroup"))
4204 i
->control_group
= s
;
4205 else if (streq(name
, "StatusText"))
4207 else if (streq(name
, "PIDFile"))
4209 else if (streq(name
, "SysFSPath"))
4211 else if (streq(name
, "Where"))
4213 else if (streq(name
, "What"))
4215 else if (streq(name
, "Following"))
4217 else if (streq(name
, "UnitFileState"))
4218 i
->unit_file_state
= s
;
4219 else if (streq(name
, "UnitFilePreset"))
4220 i
->unit_file_preset
= s
;
4221 else if (streq(name
, "Result"))
4228 case SD_BUS_TYPE_BOOLEAN
: {
4231 r
= sd_bus_message_read(m
, "b", &b
);
4233 return bus_log_parse_error(r
);
4235 if (streq(name
, "Accept"))
4237 else if (streq(name
, "NeedDaemonReload"))
4238 i
->need_daemon_reload
= b
;
4239 else if (streq(name
, "ConditionResult"))
4240 i
->condition_result
= b
;
4241 else if (streq(name
, "AssertResult"))
4242 i
->assert_result
= b
;
4243 else if (streq(name
, "Transient"))
4249 case SD_BUS_TYPE_UINT32
: {
4252 r
= sd_bus_message_read(m
, "u", &u
);
4254 return bus_log_parse_error(r
);
4256 if (streq(name
, "MainPID")) {
4258 i
->main_pid
= (pid_t
) u
;
4261 } else if (streq(name
, "ControlPID"))
4262 i
->control_pid
= (pid_t
) u
;
4263 else if (streq(name
, "ExecMainPID")) {
4265 i
->main_pid
= (pid_t
) u
;
4266 } else if (streq(name
, "NAccepted"))
4268 else if (streq(name
, "NConnections"))
4269 i
->n_connections
= u
;
4274 case SD_BUS_TYPE_INT32
: {
4277 r
= sd_bus_message_read(m
, "i", &j
);
4279 return bus_log_parse_error(r
);
4281 if (streq(name
, "ExecMainCode"))
4282 i
->exit_code
= (int) j
;
4283 else if (streq(name
, "ExecMainStatus"))
4284 i
->exit_status
= (int) j
;
4285 else if (streq(name
, "StatusErrno"))
4286 i
->status_errno
= (int) j
;
4291 case SD_BUS_TYPE_UINT64
: {
4294 r
= sd_bus_message_read(m
, "t", &u
);
4296 return bus_log_parse_error(r
);
4298 if (streq(name
, "ExecMainStartTimestamp"))
4299 i
->start_timestamp
= (usec_t
) u
;
4300 else if (streq(name
, "ExecMainExitTimestamp"))
4301 i
->exit_timestamp
= (usec_t
) u
;
4302 else if (streq(name
, "ActiveEnterTimestamp"))
4303 i
->active_enter_timestamp
= (usec_t
) u
;
4304 else if (streq(name
, "InactiveEnterTimestamp"))
4305 i
->inactive_enter_timestamp
= (usec_t
) u
;
4306 else if (streq(name
, "InactiveExitTimestamp"))
4307 i
->inactive_exit_timestamp
= (usec_t
) u
;
4308 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4309 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4310 else if (streq(name
, "ActiveExitTimestamp"))
4311 i
->active_exit_timestamp
= (usec_t
) u
;
4312 else if (streq(name
, "ConditionTimestamp"))
4313 i
->condition_timestamp
= (usec_t
) u
;
4314 else if (streq(name
, "AssertTimestamp"))
4315 i
->assert_timestamp
= (usec_t
) u
;
4316 else if (streq(name
, "MemoryCurrent"))
4317 i
->memory_current
= u
;
4318 else if (streq(name
, "MemoryLow"))
4320 else if (streq(name
, "MemoryHigh"))
4322 else if (streq(name
, "MemoryMax"))
4324 else if (streq(name
, "MemorySwapMax"))
4325 i
->memory_swap_max
= u
;
4326 else if (streq(name
, "MemoryLimit"))
4327 i
->memory_limit
= u
;
4328 else if (streq(name
, "TasksCurrent"))
4329 i
->tasks_current
= u
;
4330 else if (streq(name
, "TasksMax"))
4332 else if (streq(name
, "CPUUsageNSec"))
4333 i
->cpu_usage_nsec
= u
;
4338 case SD_BUS_TYPE_ARRAY
:
4340 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4341 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4343 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4345 return bus_log_parse_error(r
);
4347 info
= new0(ExecStatusInfo
, 1);
4351 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4353 info
->name
= strdup(name
);
4357 LIST_PREPEND(exec
, i
->exec
, info
);
4359 info
= new0(ExecStatusInfo
, 1);
4365 return bus_log_parse_error(r
);
4367 r
= sd_bus_message_exit_container(m
);
4369 return bus_log_parse_error(r
);
4373 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4374 const char *type
, *path
;
4376 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4378 return bus_log_parse_error(r
);
4380 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4382 r
= strv_extend(&i
->listen
, type
);
4386 r
= strv_extend(&i
->listen
, path
);
4391 return bus_log_parse_error(r
);
4393 r
= sd_bus_message_exit_container(m
);
4395 return bus_log_parse_error(r
);
4399 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4401 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4403 return bus_log_parse_error(r
);
4405 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4407 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4409 return bus_log_parse_error(r
);
4411 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4412 const char *cond
, *param
;
4413 int trigger
, negate
;
4416 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4418 return bus_log_parse_error(r
);
4420 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4421 _cleanup_(unit_condition_freep
) UnitCondition
*c
= NULL
;
4423 log_debug("%s trigger=%d negate=%d %s →%d", cond
, trigger
, negate
, param
, state
);
4425 c
= new0(UnitCondition
, 1);
4429 c
->name
= strdup(cond
);
4430 c
->param
= strdup(param
);
4431 if (!c
->name
|| !c
->param
)
4434 c
->trigger
= trigger
;
4436 c
->tristate
= state
;
4438 LIST_PREPEND(conditions
, i
->conditions
, c
);
4442 return bus_log_parse_error(r
);
4444 r
= sd_bus_message_exit_container(m
);
4446 return bus_log_parse_error(r
);
4448 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4449 const char *cond
, *param
;
4450 int trigger
, negate
;
4453 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4455 return bus_log_parse_error(r
);
4457 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4458 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4459 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4460 i
->failed_assert
= cond
;
4461 i
->failed_assert_trigger
= trigger
;
4462 i
->failed_assert_negate
= negate
;
4463 i
->failed_assert_parameter
= param
;
4467 return bus_log_parse_error(r
);
4469 r
= sd_bus_message_exit_container(m
);
4471 return bus_log_parse_error(r
);
4478 case SD_BUS_TYPE_STRUCT_BEGIN
:
4480 if (streq(name
, "LoadError")) {
4481 const char *n
, *message
;
4483 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4485 return bus_log_parse_error(r
);
4487 if (!isempty(message
))
4488 i
->load_error
= message
;
4501 r
= sd_bus_message_skip(m
, contents
);
4503 return bus_log_parse_error(r
);
4508 #define print_prop(name, fmt, ...) \
4511 printf(fmt "\n", __VA_ARGS__); \
4513 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4516 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4522 /* This is a low-level property printer, see
4523 * print_status_info() for the nicer output */
4525 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4526 /* skip what we didn't read */
4527 r
= sd_bus_message_skip(m
, contents
);
4531 switch (contents
[0]) {
4533 case SD_BUS_TYPE_STRUCT_BEGIN
:
4535 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4538 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4540 return bus_log_parse_error(r
);
4543 print_prop(name
, "%"PRIu32
, u
);
4545 print_prop(name
, "%s", "");
4549 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4552 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4554 return bus_log_parse_error(r
);
4556 if (arg_all
|| !isempty(s
))
4557 print_prop(name
, "%s", s
);
4561 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4562 const char *a
= NULL
, *b
= NULL
;
4564 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4566 return bus_log_parse_error(r
);
4568 if (arg_all
|| !isempty(a
) || !isempty(b
))
4569 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4572 } else if (streq_ptr(name
, "SystemCallFilter")) {
4573 _cleanup_strv_free_
char **l
= NULL
;
4576 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4578 return bus_log_parse_error(r
);
4580 r
= sd_bus_message_read(m
, "b", &whitelist
);
4582 return bus_log_parse_error(r
);
4584 r
= sd_bus_message_read_strv(m
, &l
);
4586 return bus_log_parse_error(r
);
4588 r
= sd_bus_message_exit_container(m
);
4590 return bus_log_parse_error(r
);
4592 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4597 fputs(name
, stdout
);
4604 STRV_FOREACH(i
, l
) {
4612 fputc('\n', stdout
);
4620 case SD_BUS_TYPE_ARRAY
:
4622 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4626 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4628 return bus_log_parse_error(r
);
4630 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4631 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path
, yes_no(ignore
));
4634 return bus_log_parse_error(r
);
4636 r
= sd_bus_message_exit_container(m
);
4638 return bus_log_parse_error(r
);
4642 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4643 const char *type
, *path
;
4645 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4647 return bus_log_parse_error(r
);
4649 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4650 print_prop(type
, "%s", path
);
4652 return bus_log_parse_error(r
);
4654 r
= sd_bus_message_exit_container(m
);
4656 return bus_log_parse_error(r
);
4660 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4661 const char *type
, *path
;
4663 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4665 return bus_log_parse_error(r
);
4667 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4671 printf("Listen%s=%s\n", type
, path
);
4673 return bus_log_parse_error(r
);
4675 r
= sd_bus_message_exit_container(m
);
4677 return bus_log_parse_error(r
);
4681 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4683 uint64_t value
, next_elapse
;
4685 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4687 return bus_log_parse_error(r
);
4689 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4690 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4692 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4693 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4694 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4697 return bus_log_parse_error(r
);
4699 r
= sd_bus_message_exit_container(m
);
4701 return bus_log_parse_error(r
);
4705 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4706 ExecStatusInfo info
= {};
4708 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4710 return bus_log_parse_error(r
);
4712 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4713 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4714 _cleanup_free_
char *tt
;
4716 tt
= strv_join(info
.argv
, " ");
4719 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4722 yes_no(info
.ignore
),
4723 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4724 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4726 sigchld_code_to_string(info
.code
),
4728 info
.code
== CLD_EXITED
? "" : "/",
4729 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4732 strv_free(info
.argv
);
4736 r
= sd_bus_message_exit_container(m
);
4738 return bus_log_parse_error(r
);
4742 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4743 const char *path
, *rwm
;
4745 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4747 return bus_log_parse_error(r
);
4749 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4750 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4752 return bus_log_parse_error(r
);
4754 r
= sd_bus_message_exit_container(m
);
4756 return bus_log_parse_error(r
);
4760 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4761 STR_IN_SET(name
, "IODeviceWeight", "BlockIODeviceWeight")) {
4765 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4767 return bus_log_parse_error(r
);
4769 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4770 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4772 return bus_log_parse_error(r
);
4774 r
= sd_bus_message_exit_container(m
);
4776 return bus_log_parse_error(r
);
4780 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4781 (cgroup_io_limit_type_from_string(name
) >= 0 ||
4782 STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
4786 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4788 return bus_log_parse_error(r
);
4790 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4791 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4793 return bus_log_parse_error(r
);
4795 r
= sd_bus_message_exit_container(m
);
4797 return bus_log_parse_error(r
);
4805 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4807 return bus_log_parse_error(r
);
4810 r
= sd_bus_message_skip(m
, contents
);
4812 return bus_log_parse_error(r
);
4815 printf("%s=[unprintable]\n", name
);
4821 static int show_one(
4826 bool show_properties
,
4830 static const struct bus_properties_map property_map
[] = {
4831 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
4832 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
) },
4836 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4837 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4838 _cleanup_set_free_ Set
*found_properties
= NULL
;
4839 _cleanup_(unit_status_info_free
) UnitStatusInfo info
= {
4840 .memory_current
= (uint64_t) -1,
4841 .memory_high
= CGROUP_LIMIT_MAX
,
4842 .memory_max
= CGROUP_LIMIT_MAX
,
4843 .memory_swap_max
= CGROUP_LIMIT_MAX
,
4844 .memory_limit
= (uint64_t) -1,
4845 .cpu_usage_nsec
= (uint64_t) -1,
4846 .tasks_current
= (uint64_t) -1,
4847 .tasks_max
= (uint64_t) -1,
4854 log_debug("Showing one %s", path
);
4856 r
= sd_bus_call_method(
4858 "org.freedesktop.systemd1",
4860 "org.freedesktop.DBus.Properties",
4866 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4869 r
= bus_message_map_all_properties(reply
, property_map
, &info
);
4871 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
4873 if (streq_ptr(info
.load_state
, "not-found") && streq_ptr(info
.active_state
, "inactive")) {
4874 log_full(streq(verb
, "status") ? LOG_ERR
: LOG_DEBUG
,
4875 "Unit %s could not be found.", unit
);
4877 if (streq(verb
, "status"))
4878 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
;
4880 if (!streq(verb
, "show"))
4884 r
= sd_bus_message_rewind(reply
, true);
4886 return log_error_errno(r
, "Failed to rewind: %s", bus_error_message(&error
, r
));
4889 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4891 return bus_log_parse_error(r
);
4898 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4899 const char *name
, *contents
;
4901 r
= sd_bus_message_read(reply
, "s", &name
);
4903 return bus_log_parse_error(r
);
4905 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4907 return bus_log_parse_error(r
);
4909 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4911 return bus_log_parse_error(r
);
4913 if (show_properties
) {
4914 r
= set_ensure_allocated(&found_properties
, &string_hash_ops
);
4918 r
= set_put(found_properties
, name
);
4919 if (r
< 0 && r
!= EEXIST
)
4922 r
= print_property(name
, reply
, contents
);
4924 r
= status_property(name
, reply
, &info
, contents
);
4928 r
= sd_bus_message_exit_container(reply
);
4930 return bus_log_parse_error(r
);
4932 r
= sd_bus_message_exit_container(reply
);
4934 return bus_log_parse_error(r
);
4937 return bus_log_parse_error(r
);
4939 r
= sd_bus_message_exit_container(reply
);
4941 return bus_log_parse_error(r
);
4944 if (show_properties
) {
4946 int not_found_level
= streq(verb
, "show") ? LOG_DEBUG
: LOG_WARNING
;
4948 STRV_FOREACH(pp
, arg_properties
)
4949 if (!set_contains(found_properties
, *pp
)) {
4950 log_full(not_found_level
, "Property %s does not exist.", *pp
);
4954 } else if (streq(verb
, "help"))
4955 show_unit_help(&info
);
4956 else if (streq(verb
, "status")) {
4957 print_status_info(bus
, &info
, ellipsized
);
4959 if (info
.active_state
&& !STR_IN_SET(info
.active_state
, "active", "reloading"))
4960 r
= EXIT_PROGRAM_NOT_RUNNING
;
4962 r
= EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
;
4968 static int get_unit_dbus_path_by_pid(
4973 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4974 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4978 r
= sd_bus_call_method(
4980 "org.freedesktop.systemd1",
4981 "/org/freedesktop/systemd1",
4982 "org.freedesktop.systemd1.Manager",
4988 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4990 r
= sd_bus_message_read(reply
, "o", &u
);
4992 return bus_log_parse_error(r
);
5002 static int show_all(
5005 bool show_properties
,
5009 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5010 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
5015 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
5019 pager_open(arg_no_pager
, false);
5023 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
5025 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
5026 _cleanup_free_
char *p
= NULL
;
5028 p
= unit_dbus_path_from_name(u
->id
);
5032 r
= show_one(verb
, bus
, p
, u
->id
, show_properties
, new_line
, ellipsized
);
5035 else if (r
> 0 && ret
== 0)
5042 static int show_system_status(sd_bus
*bus
) {
5043 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
5044 _cleanup_free_
char *hn
= NULL
;
5045 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
5046 const char *on
, *off
;
5049 hn
= gethostname_malloc();
5053 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
5055 return log_error_errno(r
, "Failed to read server status: %m");
5057 if (streq_ptr(mi
.state
, "degraded")) {
5058 on
= ansi_highlight_red();
5059 off
= ansi_normal();
5060 } else if (!streq_ptr(mi
.state
, "running")) {
5061 on
= ansi_highlight_yellow();
5062 off
= ansi_normal();
5066 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
5068 printf(" State: %s%s%s\n",
5069 on
, strna(mi
.state
), off
);
5071 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
5072 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
5074 printf(" Since: %s; %s\n",
5075 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
5076 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
5078 printf(" CGroup: %s\n", mi
.control_group
?: "/");
5079 if (IN_SET(arg_transport
,
5080 BUS_TRANSPORT_LOCAL
,
5081 BUS_TRANSPORT_MACHINE
)) {
5082 static const char prefix
[] = " ";
5086 if (c
> sizeof(prefix
) - 1)
5087 c
-= sizeof(prefix
) - 1;
5091 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
5097 static int show(int argc
, char *argv
[], void *userdata
) {
5098 bool show_properties
, show_status
, show_help
, new_line
= false;
5099 bool ellipsized
= false;
5105 show_properties
= streq(argv
[0], "show");
5106 show_status
= streq(argv
[0], "status");
5107 show_help
= streq(argv
[0], "help");
5109 if (show_help
&& argc
<= 1) {
5110 log_error("This command expects one or more unit names. Did you mean --help?");
5114 r
= acquire_bus(BUS_MANAGER
, &bus
);
5118 pager_open(arg_no_pager
, false);
5121 /* Increase max number of open files to 16K if we can, we
5122 * might needs this when browsing journal files, which might
5123 * be split up into many files. */
5124 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
5126 /* If no argument is specified inspect the manager itself */
5127 if (show_properties
&& argc
<= 1)
5128 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", NULL
, show_properties
, &new_line
, &ellipsized
);
5130 if (show_status
&& argc
<= 1) {
5132 show_system_status(bus
);
5136 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
5138 _cleanup_free_
char **patterns
= NULL
;
5141 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
5142 _cleanup_free_
char *path
= NULL
, *unit
= NULL
;
5145 if (safe_atou32(*name
, &id
) < 0) {
5146 if (strv_push(&patterns
, *name
) < 0)
5150 } else if (show_properties
) {
5151 /* Interpret as job id */
5152 if (asprintf(&path
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
5156 /* Interpret as PID */
5157 r
= get_unit_dbus_path_by_pid(bus
, id
, &path
);
5163 r
= unit_name_from_dbus_path(path
, &unit
);
5168 r
= show_one(argv
[0], bus
, path
, unit
, show_properties
, &new_line
, &ellipsized
);
5171 else if (r
> 0 && ret
== 0)
5175 if (!strv_isempty(patterns
)) {
5176 _cleanup_strv_free_
char **names
= NULL
;
5178 r
= expand_names(bus
, patterns
, NULL
, &names
);
5180 return log_error_errno(r
, "Failed to expand names: %m");
5182 STRV_FOREACH(name
, names
) {
5183 _cleanup_free_
char *path
;
5185 path
= unit_dbus_path_from_name(*name
);
5189 r
= show_one(argv
[0], bus
, path
, *name
, show_properties
, &new_line
, &ellipsized
);
5192 if (r
> 0 && ret
== 0)
5198 if (ellipsized
&& !arg_quiet
)
5199 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5204 static int cat_file(const char *filename
, bool newline
) {
5205 _cleanup_close_
int fd
;
5207 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
5211 printf("%s%s# %s%s\n",
5212 newline
? "\n" : "",
5213 ansi_highlight_blue(),
5218 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
5221 static int cat(int argc
, char *argv
[], void *userdata
) {
5222 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5223 _cleanup_strv_free_
char **names
= NULL
;
5229 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5230 log_error("Cannot remotely cat units.");
5234 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
5236 return log_error_errno(r
, "Failed to determine unit paths: %m");
5238 r
= acquire_bus(BUS_MANAGER
, &bus
);
5242 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5244 return log_error_errno(r
, "Failed to expand names: %m");
5246 pager_open(arg_no_pager
, false);
5248 STRV_FOREACH(name
, names
) {
5249 _cleanup_free_
char *fragment_path
= NULL
;
5250 _cleanup_strv_free_
char **dropin_paths
= NULL
;
5253 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
5264 if (fragment_path
) {
5265 r
= cat_file(fragment_path
, false);
5267 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
5270 STRV_FOREACH(path
, dropin_paths
) {
5271 r
= cat_file(*path
, path
== dropin_paths
);
5273 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
5280 static int set_property(int argc
, char *argv
[], void *userdata
) {
5281 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5282 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5283 _cleanup_free_
char *n
= NULL
;
5287 r
= acquire_bus(BUS_MANAGER
, &bus
);
5291 polkit_agent_open_if_enabled();
5293 r
= sd_bus_message_new_method_call(
5296 "org.freedesktop.systemd1",
5297 "/org/freedesktop/systemd1",
5298 "org.freedesktop.systemd1.Manager",
5299 "SetUnitProperties");
5301 return bus_log_create_error(r
);
5303 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
5305 return log_error_errno(r
, "Failed to mangle unit name: %m");
5307 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
5309 return bus_log_create_error(r
);
5311 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
5313 return bus_log_create_error(r
);
5315 r
= bus_append_unit_property_assignment_many(m
, strv_skip(argv
, 2));
5319 r
= sd_bus_message_close_container(m
);
5321 return bus_log_create_error(r
);
5323 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5325 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
5330 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5331 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5332 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5337 r
= acquire_bus(BUS_MANAGER
, &bus
);
5341 polkit_agent_open_if_enabled();
5343 switch (arg_action
) {
5350 method
= "Reexecute";
5353 case ACTION_SYSTEMCTL
:
5354 method
= streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5355 /* "daemon-reload" */ "Reload";
5359 assert_not_reached("Unexpected action");
5362 r
= sd_bus_message_new_method_call(
5365 "org.freedesktop.systemd1",
5366 "/org/freedesktop/systemd1",
5367 "org.freedesktop.systemd1.Manager",
5370 return bus_log_create_error(r
);
5372 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5373 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5374 * their timeout, and for everything else there's the same time budget in place. */
5376 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
5378 /* On reexecution, we expect a disconnect, not a reply */
5379 if (IN_SET(r
, -ETIMEDOUT
, -ECONNRESET
) && streq(method
, "Reexecute"))
5382 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5383 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5385 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5386 * old ways of doing things, hence don't log any error in that case here. */
5388 return r
< 0 ? r
: 0;
5391 static int trivial_method(int argc
, char *argv
[], void *userdata
) {
5392 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5397 r
= acquire_bus(BUS_MANAGER
, &bus
);
5401 polkit_agent_open_if_enabled();
5404 streq(argv
[0], "clear-jobs") ||
5405 streq(argv
[0], "cancel") ? "ClearJobs" :
5406 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5407 streq(argv
[0], "halt") ? "Halt" :
5408 streq(argv
[0], "reboot") ? "Reboot" :
5409 streq(argv
[0], "kexec") ? "KExec" :
5410 streq(argv
[0], "exit") ? "Exit" :
5411 /* poweroff */ "PowerOff";
5413 r
= sd_bus_call_method(
5415 "org.freedesktop.systemd1",
5416 "/org/freedesktop/systemd1",
5417 "org.freedesktop.systemd1.Manager",
5422 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5423 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5425 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5426 * old ways of doing things, hence don't log any error in that case here. */
5428 return r
< 0 ? r
: 0;
5431 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5432 _cleanup_strv_free_
char **names
= NULL
;
5438 return trivial_method(argc
, argv
, userdata
);
5440 r
= acquire_bus(BUS_MANAGER
, &bus
);
5444 polkit_agent_open_if_enabled();
5446 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5448 return log_error_errno(r
, "Failed to expand names: %m");
5450 STRV_FOREACH(name
, names
) {
5451 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5453 q
= sd_bus_call_method(
5455 "org.freedesktop.systemd1",
5456 "/org/freedesktop/systemd1",
5457 "org.freedesktop.systemd1.Manager",
5463 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5472 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5473 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5474 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5479 r
= acquire_bus(BUS_MANAGER
, &bus
);
5483 pager_open(arg_no_pager
, false);
5485 r
= sd_bus_get_property(
5487 "org.freedesktop.systemd1",
5488 "/org/freedesktop/systemd1",
5489 "org.freedesktop.systemd1.Manager",
5495 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5497 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5499 return bus_log_parse_error(r
);
5501 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5504 return bus_log_parse_error(r
);
5506 r
= sd_bus_message_exit_container(reply
);
5508 return bus_log_parse_error(r
);
5513 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5514 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5515 _cleanup_free_
char *cmdline_init
= NULL
;
5516 const char *root
, *init
;
5520 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5521 log_error("Cannot switch root remotely.");
5525 if (argc
< 2 || argc
> 3) {
5526 log_error("Wrong number of arguments.");
5535 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5536 "init", &cmdline_init
,
5539 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5541 init
= cmdline_init
;
5544 init
= empty_to_null(init
);
5546 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5548 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5549 root_init_path
= strjoina(root
, "/", init
);
5551 /* If the passed init is actually the same as the
5552 * systemd binary, then let's suppress it. */
5553 if (files_same(root_init_path
, root_systemd_path
) > 0)
5557 r
= acquire_bus(BUS_MANAGER
, &bus
);
5561 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5563 r
= sd_bus_call_method(
5565 "org.freedesktop.systemd1",
5566 "/org/freedesktop/systemd1",
5567 "org.freedesktop.systemd1.Manager",
5573 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5578 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5579 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5580 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5588 r
= acquire_bus(BUS_MANAGER
, &bus
);
5592 polkit_agent_open_if_enabled();
5594 method
= streq(argv
[0], "set-environment")
5596 : "UnsetEnvironment";
5598 r
= sd_bus_message_new_method_call(
5601 "org.freedesktop.systemd1",
5602 "/org/freedesktop/systemd1",
5603 "org.freedesktop.systemd1.Manager",
5606 return bus_log_create_error(r
);
5608 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5610 return bus_log_create_error(r
);
5612 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5614 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5619 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5620 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5621 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5625 r
= acquire_bus(BUS_MANAGER
, &bus
);
5629 polkit_agent_open_if_enabled();
5631 r
= sd_bus_message_new_method_call(
5634 "org.freedesktop.systemd1",
5635 "/org/freedesktop/systemd1",
5636 "org.freedesktop.systemd1.Manager",
5639 return bus_log_create_error(r
);
5642 r
= sd_bus_message_append_strv(m
, environ
);
5646 r
= sd_bus_message_open_container(m
, 'a', "s");
5648 return bus_log_create_error(r
);
5650 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5652 if (!env_name_is_valid(*a
)) {
5653 log_error("Not a valid environment variable name: %s", *a
);
5657 STRV_FOREACH(b
, environ
) {
5660 eq
= startswith(*b
, *a
);
5661 if (eq
&& *eq
== '=') {
5663 r
= sd_bus_message_append(m
, "s", *b
);
5665 return bus_log_create_error(r
);
5672 r
= sd_bus_message_close_container(m
);
5675 return bus_log_create_error(r
);
5677 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5679 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5684 static int enable_sysv_units(const char *verb
, char **args
) {
5687 #if defined(HAVE_SYSV_COMPAT)
5688 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5691 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5693 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5696 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5699 if (!STR_IN_SET(verb
,
5705 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5712 const char *argv
[] = {
5713 ROOTLIBEXECDIR
"/systemd-sysv-install",
5720 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5721 bool found_native
= false, found_sysv
;
5730 if (!endswith(name
, ".service"))
5733 if (path_is_absolute(name
))
5736 j
= unit_file_exists(arg_scope
, &paths
, name
);
5737 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5738 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5739 found_native
= j
!= 0;
5741 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5742 * prefer the native unit */
5743 if (found_native
&& streq(verb
, "is-enabled"))
5746 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5750 p
[strlen(p
) - strlen(".service")] = 0;
5751 found_sysv
= access(p
, F_OK
) >= 0;
5757 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5759 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5762 if (!isempty(arg_root
))
5763 argv
[c
++] = q
= strappend("--root=", arg_root
);
5766 argv
[c
++] = basename(p
);
5769 l
= strv_join((char**)argv
, " ");
5773 log_info("Executing: %s", l
);
5777 return log_error_errno(errno
, "Failed to fork: %m");
5778 else if (pid
== 0) {
5781 (void) reset_all_signal_handlers();
5782 (void) reset_signal_mask();
5784 execv(argv
[0], (char**) argv
);
5785 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
5786 _exit(EXIT_FAILURE
);
5789 j
= wait_for_terminate(pid
, &status
);
5791 return log_error_errno(j
, "Failed to wait for child: %m");
5793 if (status
.si_code
== CLD_EXITED
) {
5794 if (streq(verb
, "is-enabled")) {
5795 if (status
.si_status
== 0) {
5804 } else if (status
.si_status
!= 0)
5805 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
5807 log_error("Unexpected waitid() result.");
5814 /* Remove this entry, so that we don't try enabling it as native unit */
5817 assert(args
[f
] == name
);
5818 strv_remove(args
, name
);
5825 static int mangle_names(char **original_names
, char ***mangled_names
) {
5826 char **i
, **l
, **name
;
5829 l
= i
= new(char*, strv_length(original_names
) + 1);
5833 STRV_FOREACH(name
, original_names
) {
5835 /* When enabling units qualified path names are OK,
5836 * too, hence allow them explicitly. */
5838 if (is_path(*name
)) {
5845 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5848 return log_error_errno(r
, "Failed to mangle unit name: %m");
5861 static int normalize_names(char **names
, bool warn_if_path
) {
5863 bool was_path
= false;
5865 STRV_FOREACH(u
, names
) {
5871 r
= free_and_strdup(u
, basename(*u
));
5873 return log_error_errno(r
, "Failed to normalize unit file path: %m");
5878 if (warn_if_path
&& was_path
)
5879 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
5884 static int unit_exists(const char *unit
) {
5885 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5886 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5887 _cleanup_free_
char *path
= NULL
;
5888 static const struct bus_properties_map property_map
[] = {
5889 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
5890 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
)},
5893 UnitStatusInfo info
= {};
5897 path
= unit_dbus_path_from_name(unit
);
5901 r
= acquire_bus(BUS_MANAGER
, &bus
);
5905 r
= sd_bus_call_method(
5907 "org.freedesktop.systemd1",
5909 "org.freedesktop.DBus.Properties",
5915 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
5917 r
= bus_message_map_all_properties(reply
, property_map
, &info
);
5919 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
5921 return !streq_ptr(info
.load_state
, "not-found") || !streq_ptr(info
.active_state
, "inactive");
5924 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5925 _cleanup_strv_free_
char **names
= NULL
;
5926 const char *verb
= argv
[0];
5927 UnitFileChange
*changes
= NULL
;
5928 unsigned n_changes
= 0;
5929 int carries_install_info
= -1;
5930 bool ignore_carries_install_info
= arg_quiet
;
5936 r
= mangle_names(strv_skip(argv
, 1), &names
);
5940 r
= enable_sysv_units(verb
, names
);
5944 /* If the operation was fully executed by the SysV compat, let's finish early */
5945 if (strv_isempty(names
)) {
5946 if (arg_no_reload
|| install_client_side())
5948 return daemon_reload(argc
, argv
, userdata
);
5951 if (streq(verb
, "disable")) {
5952 r
= normalize_names(names
, true);
5957 if (install_client_side()) {
5958 if (streq(verb
, "enable")) {
5959 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5960 carries_install_info
= r
;
5961 } else if (streq(verb
, "disable"))
5962 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5963 else if (streq(verb
, "reenable")) {
5964 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5965 carries_install_info
= r
;
5966 } else if (streq(verb
, "link"))
5967 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5968 else if (streq(verb
, "preset")) {
5969 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5970 } else if (streq(verb
, "mask"))
5971 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5972 else if (streq(verb
, "unmask"))
5973 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5974 else if (streq(verb
, "revert"))
5975 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
5977 assert_not_reached("Unknown verb");
5979 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
5984 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5985 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5986 bool expect_carries_install_info
= false;
5987 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
5991 if (STR_IN_SET(verb
, "mask", "unmask")) {
5992 r
= unit_exists(*names
);
5996 log_notice("Unit %s does not exist, proceeding anyway.", *names
);
5999 r
= acquire_bus(BUS_MANAGER
, &bus
);
6003 polkit_agent_open_if_enabled();
6005 if (streq(verb
, "enable")) {
6006 method
= "EnableUnitFiles";
6007 expect_carries_install_info
= true;
6008 } else if (streq(verb
, "disable")) {
6009 method
= "DisableUnitFiles";
6011 } else if (streq(verb
, "reenable")) {
6012 method
= "ReenableUnitFiles";
6013 expect_carries_install_info
= true;
6014 } else if (streq(verb
, "link"))
6015 method
= "LinkUnitFiles";
6016 else if (streq(verb
, "preset")) {
6018 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
6019 method
= "PresetUnitFilesWithMode";
6020 send_preset_mode
= true;
6022 method
= "PresetUnitFiles";
6024 expect_carries_install_info
= true;
6025 ignore_carries_install_info
= true;
6026 } else if (streq(verb
, "mask"))
6027 method
= "MaskUnitFiles";
6028 else if (streq(verb
, "unmask")) {
6029 method
= "UnmaskUnitFiles";
6031 } else if (streq(verb
, "revert")) {
6032 method
= "RevertUnitFiles";
6033 send_runtime
= send_force
= false;
6035 assert_not_reached("Unknown verb");
6037 r
= sd_bus_message_new_method_call(
6040 "org.freedesktop.systemd1",
6041 "/org/freedesktop/systemd1",
6042 "org.freedesktop.systemd1.Manager",
6045 return bus_log_create_error(r
);
6047 r
= sd_bus_message_append_strv(m
, names
);
6049 return bus_log_create_error(r
);
6051 if (send_preset_mode
) {
6052 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
6054 return bus_log_create_error(r
);
6058 r
= sd_bus_message_append(m
, "b", arg_runtime
);
6060 return bus_log_create_error(r
);
6064 r
= sd_bus_message_append(m
, "b", arg_force
);
6066 return bus_log_create_error(r
);
6069 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6071 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
6073 if (expect_carries_install_info
) {
6074 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
6076 return bus_log_parse_error(r
);
6079 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6083 /* Try to reload if enabled */
6085 r
= daemon_reload(argc
, argv
, userdata
);
6090 if (carries_install_info
== 0 && !ignore_carries_install_info
)
6091 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6092 "settings in the [Install] section, and DefaultInstance for template units).\n"
6093 "This means they are not meant to be enabled using systemctl.\n"
6094 "Possible reasons for having this kind of units are:\n"
6095 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6096 " .wants/ or .requires/ directory.\n"
6097 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6098 " a requirement dependency on it.\n"
6099 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6100 " D-Bus, udev, scripted systemctl call, ...).\n"
6101 "4) In case of template units, the unit is meant to be enabled with some\n"
6102 " instance name specified.");
6104 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
6105 char *new_args
[n_changes
+ 2];
6109 r
= acquire_bus(BUS_MANAGER
, &bus
);
6113 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
6114 for (i
= 0; i
< n_changes
; i
++)
6115 new_args
[i
+ 1] = basename(changes
[i
].path
);
6116 new_args
[i
+ 1] = NULL
;
6118 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
6122 unit_file_changes_free(changes
, n_changes
);
6127 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
6128 _cleanup_strv_free_
char **names
= NULL
;
6129 _cleanup_free_
char *target
= NULL
;
6130 const char *verb
= argv
[0];
6131 UnitFileChange
*changes
= NULL
;
6132 unsigned n_changes
= 0;
6139 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
6141 return log_error_errno(r
, "Failed to mangle unit name: %m");
6143 r
= mangle_names(strv_skip(argv
, 2), &names
);
6147 if (streq(verb
, "add-wants"))
6149 else if (streq(verb
, "add-requires"))
6150 dep
= UNIT_REQUIRES
;
6152 assert_not_reached("Unknown verb");
6154 if (install_client_side()) {
6155 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
6156 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
6161 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6162 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6165 r
= acquire_bus(BUS_MANAGER
, &bus
);
6169 polkit_agent_open_if_enabled();
6171 r
= sd_bus_message_new_method_call(
6174 "org.freedesktop.systemd1",
6175 "/org/freedesktop/systemd1",
6176 "org.freedesktop.systemd1.Manager",
6177 "AddDependencyUnitFiles");
6179 return bus_log_create_error(r
);
6181 r
= sd_bus_message_append_strv(m
, names
);
6183 return bus_log_create_error(r
);
6185 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
6187 return bus_log_create_error(r
);
6189 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6191 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
6193 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6197 if (arg_no_reload
) {
6202 r
= daemon_reload(argc
, argv
, userdata
);
6206 unit_file_changes_free(changes
, n_changes
);
6211 static int preset_all(int argc
, char *argv
[], void *userdata
) {
6212 UnitFileChange
*changes
= NULL
;
6213 unsigned n_changes
= 0;
6216 if (install_client_side()) {
6217 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
6218 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
6223 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6224 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6227 r
= acquire_bus(BUS_MANAGER
, &bus
);
6231 polkit_agent_open_if_enabled();
6233 r
= sd_bus_call_method(
6235 "org.freedesktop.systemd1",
6236 "/org/freedesktop/systemd1",
6237 "org.freedesktop.systemd1.Manager",
6238 "PresetAllUnitFiles",
6242 unit_file_preset_mode_to_string(arg_preset_mode
),
6246 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
6248 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6252 if (arg_no_reload
) {
6257 r
= daemon_reload(argc
, argv
, userdata
);
6261 unit_file_changes_free(changes
, n_changes
);
6266 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
6268 _cleanup_strv_free_
char **names
= NULL
;
6273 r
= mangle_names(strv_skip(argv
, 1), &names
);
6277 r
= enable_sysv_units(argv
[0], names
);
6283 if (install_client_side()) {
6285 STRV_FOREACH(name
, names
) {
6286 UnitFileState state
;
6288 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
6290 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
6294 UNIT_FILE_ENABLED_RUNTIME
,
6297 UNIT_FILE_GENERATED
))
6301 puts(unit_file_state_to_string(state
));
6306 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6309 r
= acquire_bus(BUS_MANAGER
, &bus
);
6313 STRV_FOREACH(name
, names
) {
6314 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6317 r
= sd_bus_call_method(
6319 "org.freedesktop.systemd1",
6320 "/org/freedesktop/systemd1",
6321 "org.freedesktop.systemd1.Manager",
6327 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
6329 r
= sd_bus_message_read(reply
, "s", &s
);
6331 return bus_log_parse_error(r
);
6333 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6341 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
6344 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
6345 _cleanup_free_
char *state
= NULL
;
6349 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
6352 return EXIT_FAILURE
;
6355 r
= acquire_bus(BUS_MANAGER
, &bus
);
6359 r
= sd_bus_get_property_string(
6361 "org.freedesktop.systemd1",
6362 "/org/freedesktop/systemd1",
6363 "org.freedesktop.systemd1.Manager",
6376 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
6379 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
6380 _cleanup_free_
char *t
= NULL
;
6384 assert(original_path
);
6387 r
= tempfn_random(new_path
, NULL
, &t
);
6389 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
6391 r
= mkdir_parents(new_path
, 0755);
6393 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
6395 r
= copy_file(original_path
, t
, 0, 0644, 0);
6400 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
6403 return log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", new_path
);
6411 static int get_file_to_edit(
6412 const LookupPaths
*paths
,
6416 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
6421 path
= strjoin(paths
->persistent_config
, "/", name
, NULL
);
6426 run
= strjoin(paths
->runtime_config
, "/", name
, NULL
);
6432 if (access(path
, F_OK
) >= 0) {
6433 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
6447 static int unit_file_create_new(
6448 const LookupPaths
*paths
,
6449 const char *unit_name
,
6451 char **ret_new_path
,
6452 char **ret_tmp_path
) {
6454 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6458 assert(ret_new_path
);
6459 assert(ret_tmp_path
);
6461 ending
= strjoina(unit_name
, suffix
);
6462 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
6466 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6472 *ret_new_path
= tmp_new_path
;
6473 *ret_tmp_path
= tmp_tmp_path
;
6478 static int unit_file_create_copy(
6479 const LookupPaths
*paths
,
6480 const char *unit_name
,
6481 const char *fragment_path
,
6482 char **ret_new_path
,
6483 char **ret_tmp_path
) {
6485 char *tmp_new_path
, *tmp_tmp_path
;
6488 assert(fragment_path
);
6490 assert(ret_new_path
);
6491 assert(ret_tmp_path
);
6493 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6497 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6500 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6505 if (response
!= 'y') {
6506 log_warning("%s ignored", unit_name
);
6508 return -EKEYREJECTED
;
6512 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6518 *ret_new_path
= tmp_new_path
;
6519 *ret_tmp_path
= tmp_tmp_path
;
6524 static int run_editor(char **paths
) {
6532 return log_error_errno(errno
, "Failed to fork: %m");
6536 char *editor
, **editor_args
= NULL
;
6537 char **tmp_path
, **original_path
, *p
;
6538 unsigned n_editor_args
= 0, i
= 1;
6541 (void) reset_all_signal_handlers();
6542 (void) reset_signal_mask();
6544 argc
= strv_length(paths
)/2 + 1;
6546 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6547 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6548 * we try to execute well known editors
6550 editor
= getenv("SYSTEMD_EDITOR");
6552 editor
= getenv("EDITOR");
6554 editor
= getenv("VISUAL");
6556 if (!isempty(editor
)) {
6557 editor_args
= strv_split(editor
, WHITESPACE
);
6560 _exit(EXIT_FAILURE
);
6562 n_editor_args
= strv_length(editor_args
);
6563 argc
+= n_editor_args
- 1;
6565 args
= newa(const char*, argc
+ 1);
6567 if (n_editor_args
> 0) {
6568 args
[0] = editor_args
[0];
6569 for (; i
< n_editor_args
; i
++)
6570 args
[i
] = editor_args
[i
];
6573 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6574 args
[i
] = *tmp_path
;
6579 if (n_editor_args
> 0)
6580 execvp(args
[0], (char* const*) args
);
6582 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6584 execvp(p
, (char* const*) args
);
6585 /* We do not fail if the editor doesn't exist
6586 * because we want to try each one of them before
6589 if (errno
!= ENOENT
) {
6590 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6591 _exit(EXIT_FAILURE
);
6595 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6596 _exit(EXIT_FAILURE
);
6599 r
= wait_for_terminate_and_warn("editor", pid
, true);
6601 return log_error_errno(r
, "Failed to wait for child: %m");
6606 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6607 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6614 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6618 STRV_FOREACH(name
, names
) {
6619 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
;
6621 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6624 else if (!arg_force
) {
6626 log_error("Run 'systemctl edit --force %s' to create a new unit.", *name
);
6629 // FIXME: support units with path==NULL (no FragmentPath)
6630 log_error("No fragment exists for %s.", *name
);
6637 r
= unit_file_create_copy(&lp
, *name
, path
, &new_path
, &tmp_path
);
6639 r
= unit_file_create_new(&lp
, *name
, ".d/override.conf", &new_path
, &tmp_path
);
6641 r
= unit_file_create_new(&lp
, *name
, NULL
, &new_path
, &tmp_path
);
6645 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6648 new_path
= tmp_path
= NULL
;
6654 static int edit(int argc
, char *argv
[], void *userdata
) {
6655 _cleanup_strv_free_
char **names
= NULL
;
6656 _cleanup_strv_free_
char **paths
= NULL
;
6657 char **original
, **tmp
;
6662 log_error("Cannot edit units if not on a tty.");
6666 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6667 log_error("Cannot edit units remotely.");
6671 r
= acquire_bus(BUS_MANAGER
, &bus
);
6675 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6677 return log_error_errno(r
, "Failed to expand names: %m");
6679 r
= find_paths_to_edit(bus
, names
, &paths
);
6683 if (strv_isempty(paths
))
6686 r
= run_editor(paths
);
6690 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6691 /* If the temporary file is empty we ignore it. It's
6692 * useful if the user wants to cancel its modification
6694 if (null_or_empty_path(*tmp
)) {
6695 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6699 r
= rename(*tmp
, *original
);
6701 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6708 if (!arg_no_reload
&& !install_client_side())
6709 r
= daemon_reload(argc
, argv
, userdata
);
6712 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6713 (void) unlink(*tmp
);
6715 /* Removing empty dropin dirs */
6717 _cleanup_free_
char *dir
;
6719 dir
= dirname_malloc(*original
);
6723 /* no need to check if the dir is empty, rmdir
6724 * does nothing if it is not the case.
6733 static void systemctl_help(void) {
6735 pager_open(arg_no_pager
, false);
6737 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6738 "Query or send control commands to the systemd manager.\n\n"
6739 " -h --help Show this help\n"
6740 " --version Show package version\n"
6741 " --system Connect to system manager\n"
6742 " --user Connect to user service manager\n"
6743 " -H --host=[USER@]HOST\n"
6744 " Operate on remote host\n"
6745 " -M --machine=CONTAINER\n"
6746 " Operate on local container\n"
6747 " -t --type=TYPE List units of a particular type\n"
6748 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6749 " -p --property=NAME Show only properties by this name\n"
6750 " -a --all Show all properties/all units currently in memory,\n"
6751 " including dead/empty ones. To list all units installed on\n"
6752 " the system, use the 'list-unit-files' command instead.\n"
6753 " -l --full Don't ellipsize unit names on output\n"
6754 " -r --recursive Show unit list of host and local containers\n"
6755 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6756 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6757 " queueing a new job\n"
6758 " --show-types When showing sockets, explicitly show their type\n"
6759 " --value When showing properties, only print the value\n"
6760 " -i --ignore-inhibitors\n"
6761 " When shutting down or sleeping, ignore inhibitors\n"
6762 " --kill-who=WHO Who to send signal to\n"
6763 " -s --signal=SIGNAL Which signal to send\n"
6764 " --now Start or stop unit in addition to enabling or disabling it\n"
6765 " -q --quiet Suppress output\n"
6766 " --wait For (re)start, wait until service stopped again\n"
6767 " --no-block Do not wait until operation finished\n"
6768 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6769 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6770 " --no-legend Do not print a legend (column headers and hints)\n"
6771 " --no-pager Do not pipe output into a pager\n"
6772 " --no-ask-password\n"
6773 " Do not ask for system passwords\n"
6774 " --global Enable/disable unit files globally\n"
6775 " --runtime Enable unit files only temporarily until next reboot\n"
6776 " -f --force When enabling unit files, override existing symlinks\n"
6777 " When shutting down, execute action immediately\n"
6778 " --preset-mode= Apply only enable, only disable, or all presets\n"
6779 " --root=PATH Enable unit files in the specified root directory\n"
6780 " -n --lines=INTEGER Number of journal entries to show\n"
6781 " -o --output=STRING Change journal output mode (short, short-precise,\n"
6782 " short-iso, short-full, short-monotonic, short-unix,\n"
6783 " verbose, export, json, json-pretty, json-sse, cat)\n"
6784 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6785 " --plain Print unit dependencies as a list instead of a tree\n\n"
6787 " list-units [PATTERN...] List units currently in memory\n"
6788 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
6790 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
6792 " start NAME... Start (activate) one or more units\n"
6793 " stop NAME... Stop (deactivate) one or more units\n"
6794 " reload NAME... Reload one or more units\n"
6795 " restart NAME... Start or restart one or more units\n"
6796 " try-restart NAME... Restart one or more units if active\n"
6797 " reload-or-restart NAME... Reload one or more units if possible,\n"
6798 " otherwise start or restart\n"
6799 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6800 " if supported, otherwise restart\n"
6801 " isolate NAME Start one unit and stop all others\n"
6802 " kill NAME... Send signal to processes of a unit\n"
6803 " is-active PATTERN... Check whether units are active\n"
6804 " is-failed PATTERN... Check whether units are failed\n"
6805 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6806 " show [PATTERN...|JOB...] Show properties of one or more\n"
6807 " units/jobs or the manager\n"
6808 " cat PATTERN... Show files and drop-ins of one or more units\n"
6809 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6810 " help PATTERN...|PID... Show manual for one or more units\n"
6811 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6813 " list-dependencies [NAME] Recursively show units which are required\n"
6814 " or wanted by this unit or by which this\n"
6815 " unit is required or wanted\n\n"
6816 "Unit File Commands:\n"
6817 " list-unit-files [PATTERN...] List installed unit files\n"
6818 " enable [NAME...|PATH...] Enable one or more unit files\n"
6819 " disable NAME... Disable one or more unit files\n"
6820 " reenable NAME... Reenable one or more unit files\n"
6821 " preset NAME... Enable/disable one or more unit files\n"
6822 " based on preset configuration\n"
6823 " preset-all Enable/disable all unit files based on\n"
6824 " preset configuration\n"
6825 " is-enabled NAME... Check whether unit files are enabled\n"
6826 " mask NAME... Mask one or more units\n"
6827 " unmask NAME... Unmask one or more units\n"
6828 " link PATH... Link one or more units files into\n"
6829 " the search path\n"
6830 " revert NAME... Revert one or more unit files to vendor\n"
6832 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6833 " on specified one or more units\n"
6834 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6835 " on specified one or more units\n"
6836 " edit NAME... Edit one or more unit files\n"
6837 " get-default Get the name of the default target\n"
6838 " set-default NAME Set the default target\n\n"
6839 "Machine Commands:\n"
6840 " list-machines [PATTERN...] List local containers and host\n\n"
6842 " list-jobs [PATTERN...] List jobs\n"
6843 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6844 "Environment Commands:\n"
6845 " show-environment Dump environment\n"
6846 " set-environment NAME=VALUE... Set one or more environment variables\n"
6847 " unset-environment NAME... Unset one or more environment variables\n"
6848 " import-environment [NAME...] Import all or some environment variables\n\n"
6849 "Manager Lifecycle Commands:\n"
6850 " daemon-reload Reload systemd manager configuration\n"
6851 " daemon-reexec Reexecute systemd manager\n\n"
6852 "System Commands:\n"
6853 " is-system-running Check whether system is fully running\n"
6854 " default Enter system default mode\n"
6855 " rescue Enter system rescue mode\n"
6856 " emergency Enter system emergency mode\n"
6857 " halt Shut down and halt the system\n"
6858 " poweroff Shut down and power-off the system\n"
6859 " reboot [ARG] Shut down and reboot the system\n"
6860 " kexec Shut down and reboot the system with kexec\n"
6861 " exit [EXIT_CODE] Request user instance or container exit\n"
6862 " switch-root ROOT [INIT] Change to a different root file system\n"
6863 " suspend Suspend the system\n"
6864 " hibernate Hibernate the system\n"
6865 " hybrid-sleep Hibernate and suspend the system\n",
6866 program_invocation_short_name
);
6869 static void halt_help(void) {
6870 printf("%s [OPTIONS...]%s\n\n"
6871 "%s the system.\n\n"
6872 " --help Show this help\n"
6873 " --halt Halt the machine\n"
6874 " -p --poweroff Switch off the machine\n"
6875 " --reboot Reboot the machine\n"
6876 " -f --force Force immediate halt/power-off/reboot\n"
6877 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6878 " -d --no-wtmp Don't write wtmp record\n"
6879 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6880 program_invocation_short_name
,
6881 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6882 arg_action
== ACTION_REBOOT
? "Reboot" :
6883 arg_action
== ACTION_POWEROFF
? "Power off" :
6887 static void shutdown_help(void) {
6888 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6889 "Shut down the system.\n\n"
6890 " --help Show this help\n"
6891 " -H --halt Halt the machine\n"
6892 " -P --poweroff Power-off the machine\n"
6893 " -r --reboot Reboot the machine\n"
6894 " -h Equivalent to --poweroff, overridden by --halt\n"
6895 " -k Don't halt/power-off/reboot, just send warnings\n"
6896 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6897 " -c Cancel a pending shutdown\n",
6898 program_invocation_short_name
);
6901 static void telinit_help(void) {
6902 printf("%s [OPTIONS...] {COMMAND}\n\n"
6903 "Send control commands to the init daemon.\n\n"
6904 " --help Show this help\n"
6905 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6907 " 0 Power-off the machine\n"
6908 " 6 Reboot the machine\n"
6909 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6910 " 1, s, S Enter rescue mode\n"
6911 " q, Q Reload init daemon configuration\n"
6912 " u, U Reexecute init daemon\n",
6913 program_invocation_short_name
);
6916 static void runlevel_help(void) {
6917 printf("%s [OPTIONS...]\n\n"
6918 "Prints the previous and current runlevel of the init system.\n\n"
6919 " --help Show this help\n",
6920 program_invocation_short_name
);
6923 static void help_types(void) {
6927 puts("Available unit types:");
6928 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6929 puts(unit_type_to_string(i
));
6932 static void help_states(void) {
6936 puts("Available unit load states:");
6937 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6938 puts(unit_load_state_to_string(i
));
6941 puts("\nAvailable unit active states:");
6942 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6943 puts(unit_active_state_to_string(i
));
6946 puts("\nAvailable automount unit substates:");
6947 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6948 puts(automount_state_to_string(i
));
6951 puts("\nAvailable busname unit substates:");
6952 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6953 puts(busname_state_to_string(i
));
6956 puts("\nAvailable device unit substates:");
6957 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6958 puts(device_state_to_string(i
));
6961 puts("\nAvailable mount unit substates:");
6962 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6963 puts(mount_state_to_string(i
));
6966 puts("\nAvailable path unit substates:");
6967 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6968 puts(path_state_to_string(i
));
6971 puts("\nAvailable scope unit substates:");
6972 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6973 puts(scope_state_to_string(i
));
6976 puts("\nAvailable service unit substates:");
6977 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6978 puts(service_state_to_string(i
));
6981 puts("\nAvailable slice unit substates:");
6982 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6983 puts(slice_state_to_string(i
));
6986 puts("\nAvailable socket unit substates:");
6987 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6988 puts(socket_state_to_string(i
));
6991 puts("\nAvailable swap unit substates:");
6992 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6993 puts(swap_state_to_string(i
));
6996 puts("\nAvailable target unit substates:");
6997 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6998 puts(target_state_to_string(i
));
7001 puts("\nAvailable timer unit substates:");
7002 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
7003 puts(timer_state_to_string(i
));
7006 static int systemctl_parse_argv(int argc
, char *argv
[]) {
7015 ARG_IGNORE_DEPENDENCIES
,
7028 ARG_NO_ASK_PASSWORD
,
7042 static const struct option options
[] = {
7043 { "help", no_argument
, NULL
, 'h' },
7044 { "version", no_argument
, NULL
, ARG_VERSION
},
7045 { "type", required_argument
, NULL
, 't' },
7046 { "property", required_argument
, NULL
, 'p' },
7047 { "all", no_argument
, NULL
, 'a' },
7048 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
7049 { "after", no_argument
, NULL
, ARG_AFTER
},
7050 { "before", no_argument
, NULL
, ARG_BEFORE
},
7051 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
7052 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
7053 { "full", no_argument
, NULL
, 'l' },
7054 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
7055 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
7056 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
7057 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
7058 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
7059 { "value", no_argument
, NULL
, ARG_VALUE
},
7060 { "user", no_argument
, NULL
, ARG_USER
},
7061 { "system", no_argument
, NULL
, ARG_SYSTEM
},
7062 { "global", no_argument
, NULL
, ARG_GLOBAL
},
7063 { "wait", no_argument
, NULL
, ARG_WAIT
},
7064 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
7065 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
7066 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
7067 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7068 { "quiet", no_argument
, NULL
, 'q' },
7069 { "root", required_argument
, NULL
, ARG_ROOT
},
7070 { "force", no_argument
, NULL
, ARG_FORCE
},
7071 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
7072 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
7073 { "signal", required_argument
, NULL
, 's' },
7074 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
7075 { "host", required_argument
, NULL
, 'H' },
7076 { "machine", required_argument
, NULL
, 'M' },
7077 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
7078 { "lines", required_argument
, NULL
, 'n' },
7079 { "output", required_argument
, NULL
, 'o' },
7080 { "plain", no_argument
, NULL
, ARG_PLAIN
},
7081 { "state", required_argument
, NULL
, ARG_STATE
},
7082 { "recursive", no_argument
, NULL
, 'r' },
7083 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
7084 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
7085 { "now", no_argument
, NULL
, ARG_NOW
},
7086 { "message", required_argument
, NULL
, ARG_MESSAGE
},
7096 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7097 arg_ask_password
= true;
7099 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
7111 if (isempty(optarg
)) {
7112 log_error("--type requires arguments.");
7118 _cleanup_free_
char *type
= NULL
;
7120 r
= extract_first_word(&p
, &type
, ",", 0);
7122 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
7127 if (streq(type
, "help")) {
7132 if (unit_type_from_string(type
) >= 0) {
7133 if (strv_push(&arg_types
, type
) < 0)
7139 /* It's much nicer to use --state= for
7140 * load states, but let's support this
7141 * in --types= too for compatibility
7142 * with old versions */
7143 if (unit_load_state_from_string(type
) >= 0) {
7144 if (strv_push(&arg_states
, type
) < 0)
7150 log_error("Unknown unit type or load state '%s'.", type
);
7151 log_info("Use -t help to see a list of allowed values.");
7159 /* Make sure that if the empty property list
7160 was specified, we won't show any properties. */
7161 if (isempty(optarg
) && !arg_properties
) {
7162 arg_properties
= new0(char*, 1);
7163 if (!arg_properties
)
7168 _cleanup_free_
char *prop
= NULL
;
7170 r
= extract_first_word(&p
, &prop
, ",", 0);
7172 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
7177 if (strv_push(&arg_properties
, prop
) < 0)
7184 /* If the user asked for a particular
7185 * property, show it to him, even if it is
7197 arg_dependency
= DEPENDENCY_REVERSE
;
7201 arg_dependency
= DEPENDENCY_AFTER
;
7205 arg_dependency
= DEPENDENCY_BEFORE
;
7208 case ARG_SHOW_TYPES
:
7209 arg_show_types
= true;
7217 arg_job_mode
= optarg
;
7221 arg_job_mode
= "fail";
7224 case ARG_IRREVERSIBLE
:
7225 arg_job_mode
= "replace-irreversibly";
7228 case ARG_IGNORE_DEPENDENCIES
:
7229 arg_job_mode
= "ignore-dependencies";
7233 arg_scope
= UNIT_FILE_USER
;
7237 arg_scope
= UNIT_FILE_SYSTEM
;
7241 arg_scope
= UNIT_FILE_GLOBAL
;
7249 arg_no_block
= true;
7253 arg_no_legend
= true;
7257 arg_no_pager
= true;
7265 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
7275 if (strv_extend(&arg_states
, "failed") < 0)
7293 arg_no_reload
= true;
7297 arg_kill_who
= optarg
;
7301 arg_signal
= signal_from_string_try_harder(optarg
);
7302 if (arg_signal
< 0) {
7303 log_error("Failed to parse signal string %s.", optarg
);
7308 case ARG_NO_ASK_PASSWORD
:
7309 arg_ask_password
= false;
7313 arg_transport
= BUS_TRANSPORT_REMOTE
;
7318 arg_transport
= BUS_TRANSPORT_MACHINE
;
7327 if (safe_atou(optarg
, &arg_lines
) < 0) {
7328 log_error("Failed to parse lines '%s'", optarg
);
7334 arg_output
= output_mode_from_string(optarg
);
7335 if (arg_output
< 0) {
7336 log_error("Unknown output '%s'.", optarg
);
7342 arg_ignore_inhibitors
= true;
7349 case ARG_FIRMWARE_SETUP
:
7350 arg_firmware_setup
= true;
7354 if (isempty(optarg
)) {
7355 log_error("--signal requires arguments.");
7361 _cleanup_free_
char *s
= NULL
;
7363 r
= extract_first_word(&p
, &s
, ",", 0);
7365 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
7370 if (streq(s
, "help")) {
7375 if (strv_push(&arg_states
, s
) < 0)
7384 if (geteuid() != 0) {
7385 log_error("--recursive requires root privileges.");
7389 arg_recursive
= true;
7392 case ARG_PRESET_MODE
:
7394 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
7395 if (arg_preset_mode
< 0) {
7396 log_error("Failed to parse preset mode: %s.", optarg
);
7407 if (strv_extend(&arg_wall
, optarg
) < 0)
7415 assert_not_reached("Unhandled option");
7418 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
7419 log_error("Cannot access user instance remotely.");
7423 if (arg_wait
&& arg_no_block
) {
7424 log_error("--wait may not be combined with --no-block.");
7431 static int halt_parse_argv(int argc
, char *argv
[]) {
7440 static const struct option options
[] = {
7441 { "help", no_argument
, NULL
, ARG_HELP
},
7442 { "halt", no_argument
, NULL
, ARG_HALT
},
7443 { "poweroff", no_argument
, NULL
, 'p' },
7444 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
7445 { "force", no_argument
, NULL
, 'f' },
7446 { "wtmp-only", no_argument
, NULL
, 'w' },
7447 { "no-wtmp", no_argument
, NULL
, 'd' },
7448 { "no-sync", no_argument
, NULL
, 'n' },
7449 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7458 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
7459 if (runlevel
== '0' || runlevel
== '6')
7462 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
7470 arg_action
= ACTION_HALT
;
7474 if (arg_action
!= ACTION_REBOOT
)
7475 arg_action
= ACTION_POWEROFF
;
7479 arg_action
= ACTION_REBOOT
;
7504 /* Compatibility nops */
7511 assert_not_reached("Unhandled option");
7514 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7515 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7518 } else if (optind
< argc
) {
7519 log_error("Too many arguments.");
7526 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7530 if (streq(t
, "now"))
7532 else if (!strchr(t
, ':')) {
7535 if (safe_atou64(t
, &u
) < 0)
7538 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7547 hour
= strtol(t
, &e
, 10);
7548 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7551 minute
= strtol(e
+1, &e
, 10);
7552 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7555 n
= now(CLOCK_REALTIME
);
7556 s
= (time_t) (n
/ USEC_PER_SEC
);
7558 assert_se(localtime_r(&s
, &tm
));
7560 tm
.tm_hour
= (int) hour
;
7561 tm
.tm_min
= (int) minute
;
7564 assert_se(s
= mktime(&tm
));
7566 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7569 *_u
+= USEC_PER_DAY
;
7575 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7582 static const struct option options
[] = {
7583 { "help", no_argument
, NULL
, ARG_HELP
},
7584 { "halt", no_argument
, NULL
, 'H' },
7585 { "poweroff", no_argument
, NULL
, 'P' },
7586 { "reboot", no_argument
, NULL
, 'r' },
7587 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7588 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7598 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7606 arg_action
= ACTION_HALT
;
7610 arg_action
= ACTION_POWEROFF
;
7615 arg_action
= ACTION_KEXEC
;
7617 arg_action
= ACTION_REBOOT
;
7621 arg_action
= ACTION_KEXEC
;
7625 if (arg_action
!= ACTION_HALT
)
7626 arg_action
= ACTION_POWEROFF
;
7641 /* Compatibility nops */
7645 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7652 assert_not_reached("Unhandled option");
7655 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7656 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7658 log_error("Failed to parse time specification: %s", argv
[optind
]);
7662 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7664 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7665 /* No time argument for shutdown cancel */
7666 wall
= argv
+ optind
;
7667 else if (argc
> optind
+ 1)
7668 /* We skip the time argument */
7669 wall
= argv
+ optind
+ 1;
7672 arg_wall
= strv_copy(wall
);
7682 static int telinit_parse_argv(int argc
, char *argv
[]) {
7689 static const struct option options
[] = {
7690 { "help", no_argument
, NULL
, ARG_HELP
},
7691 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7695 static const struct {
7699 { '0', ACTION_POWEROFF
},
7700 { '6', ACTION_REBOOT
},
7701 { '1', ACTION_RESCUE
},
7702 { '2', ACTION_RUNLEVEL2
},
7703 { '3', ACTION_RUNLEVEL3
},
7704 { '4', ACTION_RUNLEVEL4
},
7705 { '5', ACTION_RUNLEVEL5
},
7706 { 's', ACTION_RESCUE
},
7707 { 'S', ACTION_RESCUE
},
7708 { 'q', ACTION_RELOAD
},
7709 { 'Q', ACTION_RELOAD
},
7710 { 'u', ACTION_REEXEC
},
7711 { 'U', ACTION_REEXEC
}
7720 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7735 assert_not_reached("Unhandled option");
7738 if (optind
>= argc
) {
7739 log_error("%s: required argument missing.", program_invocation_short_name
);
7743 if (optind
+ 1 < argc
) {
7744 log_error("Too many arguments.");
7748 if (strlen(argv
[optind
]) != 1) {
7749 log_error("Expected single character argument.");
7753 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7754 if (table
[i
].from
== argv
[optind
][0])
7757 if (i
>= ELEMENTSOF(table
)) {
7758 log_error("Unknown command '%s'.", argv
[optind
]);
7762 arg_action
= table
[i
].to
;
7769 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7775 static const struct option options
[] = {
7776 { "help", no_argument
, NULL
, ARG_HELP
},
7785 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7796 assert_not_reached("Unhandled option");
7799 if (optind
< argc
) {
7800 log_error("Too many arguments.");
7807 static int parse_argv(int argc
, char *argv
[]) {
7811 if (program_invocation_short_name
) {
7813 if (strstr(program_invocation_short_name
, "halt")) {
7814 arg_action
= ACTION_HALT
;
7815 return halt_parse_argv(argc
, argv
);
7816 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7817 arg_action
= ACTION_POWEROFF
;
7818 return halt_parse_argv(argc
, argv
);
7819 } else if (strstr(program_invocation_short_name
, "reboot")) {
7821 arg_action
= ACTION_KEXEC
;
7823 arg_action
= ACTION_REBOOT
;
7824 return halt_parse_argv(argc
, argv
);
7825 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7826 arg_action
= ACTION_POWEROFF
;
7827 return shutdown_parse_argv(argc
, argv
);
7828 } else if (strstr(program_invocation_short_name
, "init")) {
7830 if (sd_booted() > 0) {
7831 arg_action
= _ACTION_INVALID
;
7832 return telinit_parse_argv(argc
, argv
);
7834 /* Hmm, so some other init system is
7835 * running, we need to forward this
7836 * request to it. For now we simply
7837 * guess that it is Upstart. */
7839 execv(TELINIT
, argv
);
7841 log_error("Couldn't find an alternative telinit implementation to spawn.");
7845 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7846 arg_action
= ACTION_RUNLEVEL
;
7847 return runlevel_parse_argv(argc
, argv
);
7851 arg_action
= ACTION_SYSTEMCTL
;
7852 return systemctl_parse_argv(argc
, argv
);
7855 #ifdef HAVE_SYSV_COMPAT
7856 _pure_
static int action_to_runlevel(void) {
7858 static const char table
[_ACTION_MAX
] = {
7859 [ACTION_HALT
] = '0',
7860 [ACTION_POWEROFF
] = '0',
7861 [ACTION_REBOOT
] = '6',
7862 [ACTION_RUNLEVEL2
] = '2',
7863 [ACTION_RUNLEVEL3
] = '3',
7864 [ACTION_RUNLEVEL4
] = '4',
7865 [ACTION_RUNLEVEL5
] = '5',
7866 [ACTION_RESCUE
] = '1'
7869 assert(arg_action
< _ACTION_MAX
);
7871 return table
[arg_action
];
7875 static int talk_initctl(void) {
7876 #ifdef HAVE_SYSV_COMPAT
7877 struct init_request request
= {
7878 .magic
= INIT_MAGIC
,
7880 .cmd
= INIT_CMD_RUNLVL
7883 _cleanup_close_
int fd
= -1;
7887 rl
= action_to_runlevel();
7891 request
.runlevel
= rl
;
7893 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7895 if (errno
== ENOENT
)
7898 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7901 r
= loop_write(fd
, &request
, sizeof(request
), false);
7903 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7911 static int systemctl_main(int argc
, char *argv
[]) {
7913 static const Verb verbs
[] = {
7914 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7915 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7916 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7917 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7918 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7919 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7920 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, trivial_method
},
7921 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7922 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7923 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7924 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7925 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7926 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7927 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7928 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7929 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7930 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7931 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7932 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7933 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7934 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7935 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7936 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7937 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7938 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7939 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7940 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7941 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7942 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7943 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7944 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7945 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7946 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7947 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7948 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7949 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7950 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7951 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_system_special
},
7952 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7953 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7954 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7955 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7956 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7957 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7958 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7959 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7960 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7961 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7962 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7963 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7964 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7965 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7966 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7967 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7968 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7969 { "link", 2, VERB_ANY
, 0, enable_unit
},
7970 { "revert", 2, VERB_ANY
, 0, enable_unit
},
7971 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7972 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7973 { "set-default", 2, 2, 0, set_default
},
7974 { "get-default", VERB_ANY
, 1, 0, get_default
},
7975 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7976 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7977 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7978 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7979 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7983 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7986 static int reload_with_fallback(void) {
7988 /* First, try systemd via D-Bus. */
7989 if (daemon_reload(0, NULL
, NULL
) >= 0)
7992 /* Nothing else worked, so let's try signals */
7993 assert(IN_SET(arg_action
, ACTION_RELOAD
, ACTION_REEXEC
));
7995 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7996 return log_error_errno(errno
, "kill() failed: %m");
8001 static int start_with_fallback(void) {
8003 /* First, try systemd via D-Bus. */
8004 if (start_unit(0, NULL
, NULL
) >= 0)
8007 /* Nothing else worked, so let's try /dev/initctl */
8008 if (talk_initctl() > 0)
8011 log_error("Failed to talk to init daemon.");
8015 static int halt_now(enum action a
) {
8018 /* The kernel will automaticall flush ATA disks and suchlike
8019 * on reboot(), but the file systems need to be synce'd
8020 * explicitly in advance. */
8024 /* Make sure C-A-D is handled by the kernel from this point
8026 (void) reboot(RB_ENABLE_CAD
);
8031 log_info("Halting.");
8032 (void) reboot(RB_HALT_SYSTEM
);
8035 case ACTION_POWEROFF
:
8036 log_info("Powering off.");
8037 (void) reboot(RB_POWER_OFF
);
8041 case ACTION_REBOOT
: {
8042 _cleanup_free_
char *param
= NULL
;
8044 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
8046 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
8048 if (!isempty(param
)) {
8049 log_info("Rebooting with argument '%s'.", param
);
8050 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
8051 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
8054 log_info("Rebooting.");
8055 (void) reboot(RB_AUTOBOOT
);
8060 assert_not_reached("Unknown action.");
8064 static int logind_schedule_shutdown(void) {
8067 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8068 char date
[FORMAT_TIMESTAMP_MAX
];
8073 r
= acquire_bus(BUS_FULL
, &bus
);
8077 switch (arg_action
) {
8081 case ACTION_POWEROFF
:
8082 action
= "poweroff";
8097 action
= strjoina("dry-", action
);
8099 (void) logind_set_wall_message();
8101 r
= sd_bus_call_method(
8103 "org.freedesktop.login1",
8104 "/org/freedesktop/login1",
8105 "org.freedesktop.login1.Manager",
8113 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
8115 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
8118 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8123 static int halt_main(void) {
8126 r
= logind_check_inhibitors(arg_action
);
8131 return logind_schedule_shutdown();
8133 if (geteuid() != 0) {
8134 if (arg_dry
|| arg_force
> 0) {
8135 log_error("Must be root.");
8139 /* Try logind if we are a normal user and no special
8140 * mode applies. Maybe PolicyKit allows us to shutdown
8142 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
8143 r
= logind_reboot(arg_action
);
8146 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
8147 /* requested operation is not
8148 * supported on the local system or
8149 * already in progress */
8151 /* on all other errors, try low-level operation */
8155 if (!arg_dry
&& !arg_force
)
8156 return start_with_fallback();
8158 assert(geteuid() == 0);
8161 if (sd_booted() > 0)
8162 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8164 r
= utmp_put_shutdown();
8166 log_warning_errno(r
, "Failed to write utmp record: %m");
8173 r
= halt_now(arg_action
);
8174 return log_error_errno(r
, "Failed to reboot: %m");
8177 static int runlevel_main(void) {
8178 int r
, runlevel
, previous
;
8180 r
= utmp_get_runlevel(&runlevel
, &previous
);
8187 previous
<= 0 ? 'N' : previous
,
8188 runlevel
<= 0 ? 'N' : runlevel
);
8193 static int logind_cancel_shutdown(void) {
8195 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8199 r
= acquire_bus(BUS_FULL
, &bus
);
8203 (void) logind_set_wall_message();
8205 r
= sd_bus_call_method(
8207 "org.freedesktop.login1",
8208 "/org/freedesktop/login1",
8209 "org.freedesktop.login1.Manager",
8210 "CancelScheduledShutdown",
8214 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
8218 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8223 int main(int argc
, char*argv
[]) {
8226 setlocale(LC_ALL
, "");
8227 log_parse_environment();
8231 /* Explicitly not on_tty() to avoid setting cached value.
8232 * This becomes relevant for piping output which might be
8234 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
8236 r
= parse_argv(argc
, argv
);
8240 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
8241 log_info("Running in chroot, ignoring request.");
8246 /* systemctl_main() will print an error message for the bus
8247 * connection, but only if it needs to */
8249 switch (arg_action
) {
8251 case ACTION_SYSTEMCTL
:
8252 r
= systemctl_main(argc
, argv
);
8256 case ACTION_POWEROFF
:
8262 case ACTION_RUNLEVEL2
:
8263 case ACTION_RUNLEVEL3
:
8264 case ACTION_RUNLEVEL4
:
8265 case ACTION_RUNLEVEL5
:
8267 case ACTION_EMERGENCY
:
8268 case ACTION_DEFAULT
:
8269 r
= start_with_fallback();
8274 r
= reload_with_fallback();
8277 case ACTION_CANCEL_SHUTDOWN
:
8278 r
= logind_cancel_shutdown();
8281 case ACTION_RUNLEVEL
:
8282 r
= runlevel_main();
8285 case _ACTION_INVALID
:
8287 assert_not_reached("Unknown action");
8294 ask_password_agent_close();
8295 polkit_agent_close();
8297 strv_free(arg_types
);
8298 strv_free(arg_states
);
8299 strv_free(arg_properties
);
8301 strv_free(arg_wall
);
8304 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8305 return r
< 0 ? EXIT_FAILURE
: r
;