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 UnitFileFlags
args_to_flags(void) {
193 return (arg_runtime
? UNIT_FILE_RUNTIME
: 0) |
194 (arg_force
? UNIT_FILE_FORCE
: 0);
197 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
200 assert(focus
< _BUS_FOCUS_MAX
);
203 /* We only go directly to the manager, if we are using a local transport */
204 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
207 if (!busses
[focus
]) {
210 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
212 if (focus
== BUS_MANAGER
)
213 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
215 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
217 return log_error_errno(r
, "Failed to connect to bus: %m");
219 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
222 *ret
= busses
[focus
];
226 static void release_busses(void) {
229 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
230 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
233 static int map_string_no_copy(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
235 const char **p
= userdata
;
238 r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &s
);
248 static void ask_password_agent_open_if_enabled(void) {
250 /* Open the password agent as a child process if necessary */
252 if (!arg_ask_password
)
255 if (arg_scope
!= UNIT_FILE_SYSTEM
)
258 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
261 ask_password_agent_open();
264 static void polkit_agent_open_if_enabled(void) {
266 /* Open the polkit agent as a child process if necessary */
268 if (!arg_ask_password
)
271 if (arg_scope
!= UNIT_FILE_SYSTEM
)
274 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
280 static OutputFlags
get_output_flags(void) {
282 arg_all
* OUTPUT_SHOW_ALL
|
283 arg_full
* OUTPUT_FULL_WIDTH
|
284 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
285 colors_enabled() * OUTPUT_COLOR
|
286 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
289 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
292 if (!sd_bus_error_is_set(error
))
295 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
296 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
297 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
298 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
299 return EXIT_NOPERMISSION
;
301 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
302 return EXIT_NOTINSTALLED
;
304 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
305 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
306 return EXIT_NOTIMPLEMENTED
;
308 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
309 return EXIT_NOTCONFIGURED
;
317 static bool install_client_side(void) {
319 /* Decides when to execute enable/disable/... operations
320 * client-side rather than server-side. */
322 if (running_in_chroot() > 0)
325 if (sd_booted() <= 0)
328 if (!isempty(arg_root
))
331 if (arg_scope
== UNIT_FILE_GLOBAL
)
334 /* Unsupported environment variable, mostly for debugging purposes */
335 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
341 static int compare_unit_info(const void *a
, const void *b
) {
342 const UnitInfo
*u
= a
, *v
= b
;
346 /* First, order by machine */
347 if (!u
->machine
&& v
->machine
)
349 if (u
->machine
&& !v
->machine
)
351 if (u
->machine
&& v
->machine
) {
352 r
= strcasecmp(u
->machine
, v
->machine
);
357 /* Second, order by unit type */
358 d1
= strrchr(u
->id
, '.');
359 d2
= strrchr(v
->id
, '.');
361 r
= strcasecmp(d1
, d2
);
366 /* Third, order by name */
367 return strcasecmp(u
->id
, v
->id
);
370 static const char* unit_type_suffix(const char *name
) {
373 dot
= strrchr(name
, '.');
380 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
383 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
386 if (arg_types
&& !strv_find(arg_types
, unit_type_suffix(u
->id
)))
392 /* Note that '--all' is not purely a state filter, but also a
393 * filter that hides units that "follow" other units (which is
394 * used for device units that appear under different names). */
395 if (!isempty(u
->following
))
398 if (!strv_isempty(arg_states
))
401 /* By default show all units except the ones in inactive
402 * state and with no pending job */
406 if (streq(u
->active_state
, "inactive"))
412 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
413 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
;
415 unsigned n_shown
= 0;
416 int job_count
= 0, desc_len
;
418 max_id_len
= strlen("UNIT");
419 load_len
= strlen("LOAD");
420 active_len
= strlen("ACTIVE");
421 sub_len
= strlen("SUB");
422 job_len
= strlen("JOB");
425 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
426 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
427 load_len
= MAX(load_len
, strlen(u
->load_state
));
428 active_len
= MAX(active_len
, strlen(u
->active_state
));
429 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
431 if (u
->job_id
!= 0) {
432 job_len
= MAX(job_len
, strlen(u
->job_type
));
436 if (!arg_no_legend
&&
437 (streq(u
->active_state
, "failed") ||
438 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
442 if (!arg_full
&& original_stdout_is_tty
) {
445 id_len
= MIN(max_id_len
, 25u);
446 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
449 basic_len
+= job_len
+ 1;
451 if (basic_len
< (unsigned) columns()) {
452 unsigned extra_len
, incr
;
453 extra_len
= columns() - basic_len
;
455 /* Either UNIT already got 25, or is fully satisfied.
456 * Grant up to 25 to DESC now. */
457 incr
= MIN(extra_len
, 25u);
461 /* split the remaining space between UNIT and DESC,
462 * but do not give UNIT more than it needs. */
464 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
466 desc_len
+= extra_len
- incr
;
472 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
473 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
474 const char *on_underline
= "", *off_underline
= "";
475 const char *on_loaded
= "", *off_loaded
= "";
476 const char *on_active
= "", *off_active
= "";
477 const char *on_circle
= "", *off_circle
= "";
479 bool circle
= false, underline
= false;
481 if (!n_shown
&& !arg_no_legend
) {
486 printf("%s%-*s %-*s %-*s %-*s ",
490 active_len
, "ACTIVE",
494 printf("%-*s ", job_len
, "JOB");
497 !arg_full
&& arg_no_pager
? desc_len
: -1,
504 if (u
+ 1 < unit_infos
+ c
&&
505 !streq(unit_type_suffix(u
->id
), unit_type_suffix((u
+ 1)->id
))) {
506 on_underline
= ansi_underline();
507 off_underline
= ansi_normal();
511 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
512 on_circle
= ansi_highlight_yellow();
513 off_circle
= ansi_normal();
515 on_loaded
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
516 off_loaded
= underline
? on_underline
: ansi_normal();
517 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
518 on_circle
= ansi_highlight_red();
519 off_circle
= ansi_normal();
521 on_active
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
522 off_active
= underline
? on_underline
: ansi_normal();
526 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
535 e
= ellipsize(id
, id_len
, 33);
543 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
545 printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
547 on_active
, id_len
, id
, off_active
,
548 on_loaded
, load_len
, u
->load_state
, off_loaded
,
549 on_active
, active_len
, u
->active_state
,
550 sub_len
, u
->sub_state
, off_active
,
551 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
554 desc_len
> 0 ? desc_len
: -1,
559 if (!arg_no_legend
) {
560 const char *on
, *off
;
564 "LOAD = Reflects whether the unit definition was properly loaded.\n"
565 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
566 "SUB = The low-level unit activation state, values depend on unit type.");
567 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
568 on
= ansi_highlight();
571 on
= ansi_highlight_red();
576 printf("%s%u loaded units listed.%s\n"
577 "To show all installed unit files use 'systemctl list-unit-files'.\n",
580 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
581 "To show all installed unit files use 'systemctl list-unit-files'.\n",
588 static int get_unit_list(
592 UnitInfo
**unit_infos
,
594 sd_bus_message
**_reply
) {
596 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
597 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
598 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
602 bool fallback
= false;
608 r
= sd_bus_message_new_method_call(
611 "org.freedesktop.systemd1",
612 "/org/freedesktop/systemd1",
613 "org.freedesktop.systemd1.Manager",
614 "ListUnitsByPatterns");
616 return bus_log_create_error(r
);
618 r
= sd_bus_message_append_strv(m
, arg_states
);
620 return bus_log_create_error(r
);
622 r
= sd_bus_message_append_strv(m
, patterns
);
624 return bus_log_create_error(r
);
626 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
627 if (r
< 0 && (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
) ||
628 sd_bus_error_has_name(&error
, SD_BUS_ERROR_ACCESS_DENIED
))) {
629 /* Fallback to legacy ListUnitsFiltered method */
631 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
632 m
= sd_bus_message_unref(m
);
633 sd_bus_error_free(&error
);
635 r
= sd_bus_message_new_method_call(
638 "org.freedesktop.systemd1",
639 "/org/freedesktop/systemd1",
640 "org.freedesktop.systemd1.Manager",
641 "ListUnitsFiltered");
643 return bus_log_create_error(r
);
645 r
= sd_bus_message_append_strv(m
, arg_states
);
647 return bus_log_create_error(r
);
649 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
652 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
654 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
656 return bus_log_parse_error(r
);
658 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
661 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
664 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
667 (*unit_infos
)[c
++] = u
;
670 return bus_log_parse_error(r
);
672 r
= sd_bus_message_exit_container(reply
);
674 return bus_log_parse_error(r
);
682 static void message_set_freep(Set
**set
) {
685 while ((m
= set_steal_first(*set
)))
686 sd_bus_message_unref(m
);
691 static int get_unit_list_recursive(
694 UnitInfo
**_unit_infos
,
698 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
699 _cleanup_(message_set_freep
) Set
*replies
;
700 sd_bus_message
*reply
;
708 replies
= set_new(NULL
);
712 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
716 r
= set_put(replies
, reply
);
718 sd_bus_message_unref(reply
);
723 _cleanup_strv_free_
char **machines
= NULL
;
726 r
= sd_get_machine_names(&machines
);
728 return log_error_errno(r
, "Failed to get machine names: %m");
730 STRV_FOREACH(i
, machines
) {
731 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
734 r
= sd_bus_open_system_machine(&container
, *i
);
736 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
740 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
746 r
= set_put(replies
, reply
);
748 sd_bus_message_unref(reply
);
753 *_machines
= machines
;
758 *_unit_infos
= unit_infos
;
767 static int list_units(int argc
, char *argv
[], void *userdata
) {
768 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
769 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
770 _cleanup_strv_free_
char **machines
= NULL
;
774 r
= acquire_bus(BUS_MANAGER
, &bus
);
778 pager_open(arg_no_pager
, false);
780 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
784 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
785 return output_units_list(unit_infos
, r
);
788 static int get_triggered_units(
793 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
800 r
= sd_bus_get_property_strv(
802 "org.freedesktop.systemd1",
804 "org.freedesktop.systemd1.Unit",
809 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
814 static int get_listening(
816 const char* unit_path
,
819 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
820 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
821 const char *type
, *path
;
824 r
= sd_bus_get_property(
826 "org.freedesktop.systemd1",
828 "org.freedesktop.systemd1.Socket",
834 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
836 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
838 return bus_log_parse_error(r
);
840 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
842 r
= strv_extend(listening
, type
);
846 r
= strv_extend(listening
, path
);
853 return bus_log_parse_error(r
);
855 r
= sd_bus_message_exit_container(reply
);
857 return bus_log_parse_error(r
);
869 /* Note: triggered is a list here, although it almost certainly
870 * will always be one unit. Nevertheless, dbus API allows for multiple
871 * values, so let's follow that. */
874 /* The strv above is shared. free is set only in the first one. */
878 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
884 if (!a
->machine
&& b
->machine
)
886 if (a
->machine
&& !b
->machine
)
888 if (a
->machine
&& b
->machine
) {
889 o
= strcasecmp(a
->machine
, b
->machine
);
894 o
= strcmp(a
->path
, b
->path
);
896 o
= strcmp(a
->type
, b
->type
);
901 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
902 struct socket_info
*s
;
903 unsigned pathlen
= strlen("LISTEN"),
904 typelen
= strlen("TYPE") * arg_show_types
,
905 socklen
= strlen("UNIT"),
906 servlen
= strlen("ACTIVATES");
907 const char *on
, *off
;
909 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
913 socklen
= MAX(socklen
, strlen(s
->id
));
915 typelen
= MAX(typelen
, strlen(s
->type
));
916 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
918 STRV_FOREACH(a
, s
->triggered
)
919 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
920 servlen
= MAX(servlen
, tmp
);
925 printf("%-*s %-*.*s%-*s %s\n",
927 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
931 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
932 _cleanup_free_
char *j
= NULL
;
937 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
945 printf("%-*s %-*s %-*s",
946 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
949 pathlen
, path
, socklen
, s
->id
);
950 STRV_FOREACH(a
, s
->triggered
)
952 a
== s
->triggered
? "" : ",", *a
);
956 on
= ansi_highlight();
961 on
= ansi_highlight_red();
965 if (!arg_no_legend
) {
966 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
968 printf("Pass --all to see loaded but inactive sockets, too.\n");
974 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
975 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
976 _cleanup_strv_free_
char **machines
= NULL
;
977 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
978 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
980 struct socket_info
*s
;
986 r
= acquire_bus(BUS_MANAGER
, &bus
);
990 pager_open(arg_no_pager
, false);
992 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
996 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
997 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
1000 if (!endswith(u
->id
, ".socket"))
1003 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1007 c
= get_listening(bus
, u
->unit_path
, &listening
);
1013 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
1018 for (i
= 0; i
< c
; i
++)
1019 socket_infos
[cs
+ i
] = (struct socket_info
) {
1020 .machine
= u
->machine
,
1022 .type
= listening
[i
*2],
1023 .path
= listening
[i
*2 + 1],
1024 .triggered
= triggered
,
1025 .own_triggered
= i
==0,
1028 /* from this point on we will cleanup those socket_infos */
1031 listening
= triggered
= NULL
; /* avoid cleanup */
1034 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
1035 (__compar_fn_t
) socket_info_compare
);
1037 output_sockets_list(socket_infos
, cs
);
1040 assert(cs
== 0 || socket_infos
);
1041 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
1044 if (s
->own_triggered
)
1045 strv_free(s
->triggered
);
1051 static int get_next_elapse(
1054 dual_timestamp
*next
) {
1056 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1064 r
= sd_bus_get_property_trivial(
1066 "org.freedesktop.systemd1",
1068 "org.freedesktop.systemd1.Timer",
1069 "NextElapseUSecMonotonic",
1074 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1076 r
= sd_bus_get_property_trivial(
1078 "org.freedesktop.systemd1",
1080 "org.freedesktop.systemd1.Timer",
1081 "NextElapseUSecRealtime",
1086 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1092 static int get_last_trigger(
1097 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1104 r
= sd_bus_get_property_trivial(
1106 "org.freedesktop.systemd1",
1108 "org.freedesktop.systemd1.Timer",
1114 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1120 const char* machine
;
1123 usec_t last_trigger
;
1127 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1133 if (!a
->machine
&& b
->machine
)
1135 if (a
->machine
&& !b
->machine
)
1137 if (a
->machine
&& b
->machine
) {
1138 o
= strcasecmp(a
->machine
, b
->machine
);
1143 if (a
->next_elapse
< b
->next_elapse
)
1145 if (a
->next_elapse
> b
->next_elapse
)
1148 return strcmp(a
->id
, b
->id
);
1151 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1152 struct timer_info
*t
;
1154 nextlen
= strlen("NEXT"),
1155 leftlen
= strlen("LEFT"),
1156 lastlen
= strlen("LAST"),
1157 passedlen
= strlen("PASSED"),
1158 unitlen
= strlen("UNIT"),
1159 activatelen
= strlen("ACTIVATES");
1161 const char *on
, *off
;
1163 assert(timer_infos
|| n
== 0);
1165 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1169 if (t
->next_elapse
> 0) {
1170 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1172 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1173 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1175 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1176 leftlen
= MAX(leftlen
, strlen(trel
));
1179 if (t
->last_trigger
> 0) {
1180 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1182 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1183 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1185 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1186 passedlen
= MAX(passedlen
, strlen(trel
));
1189 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1191 STRV_FOREACH(a
, t
->triggered
)
1192 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1194 activatelen
= MAX(activatelen
, ul
);
1199 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1203 passedlen
, "PASSED",
1207 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1208 _cleanup_free_
char *j
= NULL
;
1210 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1211 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1214 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1215 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1217 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1218 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1221 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1228 printf("%-*s %-*s %-*s %-*s %-*s",
1229 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1231 STRV_FOREACH(a
, t
->triggered
)
1233 a
== t
->triggered
? "" : ",", *a
);
1237 on
= ansi_highlight();
1238 off
= ansi_normal();
1242 on
= ansi_highlight_red();
1243 off
= ansi_normal();
1246 if (!arg_no_legend
) {
1247 printf("%s%u timers listed.%s\n", on
, n
, off
);
1249 printf("Pass --all to see loaded but inactive timers, too.\n");
1255 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1261 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1264 if (next
->monotonic
> nw
->monotonic
)
1265 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1267 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1269 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1270 next_elapse
= MIN(converted
, next
->realtime
);
1272 next_elapse
= converted
;
1275 next_elapse
= next
->realtime
;
1280 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1281 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1282 _cleanup_strv_free_
char **machines
= NULL
;
1283 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1284 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1285 struct timer_info
*t
;
1293 r
= acquire_bus(BUS_MANAGER
, &bus
);
1297 pager_open(arg_no_pager
, false);
1299 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1303 dual_timestamp_get(&nw
);
1305 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1306 _cleanup_strv_free_
char **triggered
= NULL
;
1307 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1310 if (!endswith(u
->id
, ".timer"))
1313 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1317 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1321 get_last_trigger(bus
, u
->unit_path
, &last
);
1323 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1328 m
= calc_next_elapse(&nw
, &next
);
1330 timer_infos
[c
++] = (struct timer_info
) {
1331 .machine
= u
->machine
,
1334 .last_trigger
= last
,
1335 .triggered
= triggered
,
1338 triggered
= NULL
; /* avoid cleanup */
1341 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1342 (__compar_fn_t
) timer_info_compare
);
1344 output_timers_list(timer_infos
, c
);
1347 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1348 strv_free(t
->triggered
);
1353 static int compare_unit_file_list(const void *a
, const void *b
) {
1354 const char *d1
, *d2
;
1355 const UnitFileList
*u
= a
, *v
= b
;
1357 d1
= strrchr(u
->path
, '.');
1358 d2
= strrchr(v
->path
, '.');
1363 r
= strcasecmp(d1
, d2
);
1368 return strcasecmp(basename(u
->path
), basename(v
->path
));
1371 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1374 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1377 if (!strv_isempty(arg_types
)) {
1380 dot
= strrchr(u
->path
, '.');
1384 if (!strv_find(arg_types
, dot
+1))
1388 if (!strv_isempty(states
) &&
1389 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1395 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1396 unsigned max_id_len
, id_cols
, state_cols
;
1397 const UnitFileList
*u
;
1399 max_id_len
= strlen("UNIT FILE");
1400 state_cols
= strlen("STATE");
1402 for (u
= units
; u
< units
+ c
; u
++) {
1403 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1404 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1408 unsigned basic_cols
;
1410 id_cols
= MIN(max_id_len
, 25u);
1411 basic_cols
= 1 + id_cols
+ state_cols
;
1412 if (basic_cols
< (unsigned) columns())
1413 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1415 id_cols
= max_id_len
;
1417 if (!arg_no_legend
&& c
> 0)
1418 printf("%s%-*s %-*s%s\n",
1420 id_cols
, "UNIT FILE",
1421 state_cols
, "STATE",
1424 for (u
= units
; u
< units
+ c
; u
++) {
1425 _cleanup_free_
char *e
= NULL
;
1426 const char *on
, *off
, *on_underline
= "", *off_underline
= "";
1428 bool underline
= false;
1430 if (u
+ 1 < units
+ c
&&
1431 !streq(unit_type_suffix(u
->path
), unit_type_suffix((u
+ 1)->path
))) {
1432 on_underline
= ansi_underline();
1433 off_underline
= ansi_normal();
1437 if (IN_SET(u
->state
,
1439 UNIT_FILE_MASKED_RUNTIME
,
1442 on
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
1443 else if (u
->state
== UNIT_FILE_ENABLED
)
1444 on
= underline
? ansi_highlight_green_underline() : ansi_highlight_green();
1447 off
= off_underline
;
1449 id
= basename(u
->path
);
1451 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1453 printf("%s%-*s %s%-*s%s%s\n",
1455 id_cols
, e
? e
: id
,
1456 on
, state_cols
, unit_file_state_to_string(u
->state
), off
,
1461 printf("\n%u unit files listed.\n", c
);
1464 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1465 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1466 _cleanup_free_ UnitFileList
*units
= NULL
;
1473 bool fallback
= false;
1475 if (install_client_side()) {
1481 h
= hashmap_new(&string_hash_ops
);
1485 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1487 unit_file_list_free(h
);
1488 return log_error_errno(r
, "Failed to get unit file list: %m");
1491 n_units
= hashmap_size(h
);
1493 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1495 unit_file_list_free(h
);
1499 HASHMAP_FOREACH(u
, h
, i
) {
1500 if (!output_show_unit_file(u
, NULL
, NULL
))
1507 assert(c
<= n_units
);
1512 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1513 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1516 r
= acquire_bus(BUS_MANAGER
, &bus
);
1520 r
= sd_bus_message_new_method_call(
1523 "org.freedesktop.systemd1",
1524 "/org/freedesktop/systemd1",
1525 "org.freedesktop.systemd1.Manager",
1526 "ListUnitFilesByPatterns");
1528 return bus_log_create_error(r
);
1530 r
= sd_bus_message_append_strv(m
, arg_states
);
1532 return bus_log_create_error(r
);
1534 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1536 return bus_log_create_error(r
);
1538 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1539 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1540 /* Fallback to legacy ListUnitFiles method */
1542 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1543 m
= sd_bus_message_unref(m
);
1544 sd_bus_error_free(&error
);
1546 r
= sd_bus_message_new_method_call(
1549 "org.freedesktop.systemd1",
1550 "/org/freedesktop/systemd1",
1551 "org.freedesktop.systemd1.Manager",
1554 return bus_log_create_error(r
);
1556 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1559 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1561 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1563 return bus_log_parse_error(r
);
1565 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1567 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1570 units
[c
] = (struct UnitFileList
) {
1572 unit_file_state_from_string(state
)
1575 if (output_show_unit_file(&units
[c
],
1576 fallback
? arg_states
: NULL
,
1577 fallback
? strv_skip(argv
, 1) : NULL
))
1582 return bus_log_parse_error(r
);
1584 r
= sd_bus_message_exit_container(reply
);
1586 return bus_log_parse_error(r
);
1589 pager_open(arg_no_pager
, false);
1591 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1592 output_unit_file_list(units
, c
);
1594 if (install_client_side())
1595 for (unit
= units
; unit
< units
+ c
; unit
++)
1601 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1602 _cleanup_free_
char *n
= NULL
;
1603 size_t max_len
= MAX(columns(),20u);
1609 for (i
= level
- 1; i
>= 0; i
--) {
1611 if (len
> max_len
- 3 && !arg_full
) {
1612 printf("%s...\n",max_len
% 2 ? "" : " ");
1615 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1619 if (len
> max_len
- 3 && !arg_full
) {
1620 printf("%s...\n",max_len
% 2 ? "" : " ");
1624 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1628 printf("%s\n", name
);
1632 n
= ellipsize(name
, max_len
-len
, 100);
1640 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1642 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1643 [DEPENDENCY_FORWARD
] = "Requires\0"
1648 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1653 [DEPENDENCY_AFTER
] = "After\0",
1654 [DEPENDENCY_BEFORE
] = "Before\0",
1657 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1658 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1659 _cleanup_strv_free_
char **ret
= NULL
;
1660 _cleanup_free_
char *path
= NULL
;
1666 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1668 path
= unit_dbus_path_from_name(name
);
1672 r
= sd_bus_call_method(
1674 "org.freedesktop.systemd1",
1676 "org.freedesktop.DBus.Properties",
1680 "s", "org.freedesktop.systemd1.Unit");
1682 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1684 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1686 return bus_log_parse_error(r
);
1688 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1691 r
= sd_bus_message_read(reply
, "s", &prop
);
1693 return bus_log_parse_error(r
);
1695 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1696 r
= sd_bus_message_skip(reply
, "v");
1698 return bus_log_parse_error(r
);
1701 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1703 return bus_log_parse_error(r
);
1705 r
= bus_message_read_strv_extend(reply
, &ret
);
1707 return bus_log_parse_error(r
);
1709 r
= sd_bus_message_exit_container(reply
);
1711 return bus_log_parse_error(r
);
1714 r
= sd_bus_message_exit_container(reply
);
1716 return bus_log_parse_error(r
);
1720 return bus_log_parse_error(r
);
1722 r
= sd_bus_message_exit_container(reply
);
1724 return bus_log_parse_error(r
);
1732 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1733 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1735 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1737 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1740 return strcasecmp(*a
, *b
);
1743 static int list_dependencies_one(
1748 unsigned int branches
) {
1750 _cleanup_strv_free_
char **deps
= NULL
;
1758 r
= strv_extend(units
, name
);
1762 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1766 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1768 STRV_FOREACH(c
, deps
) {
1769 if (strv_contains(*units
, *c
)) {
1771 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1781 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1784 (void) get_state_one_unit(bus
, *c
, &active_state
);
1786 switch (active_state
) {
1788 case UNIT_RELOADING
:
1789 case UNIT_ACTIVATING
:
1790 on
= ansi_highlight_green();
1794 case UNIT_DEACTIVATING
:
1799 on
= ansi_highlight_red();
1803 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1806 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1810 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1811 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1818 strv_remove(*units
, name
);
1823 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1824 _cleanup_strv_free_
char **units
= NULL
;
1825 _cleanup_free_
char *unit
= NULL
;
1831 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1833 return log_error_errno(r
, "Failed to mangle unit name: %m");
1837 u
= SPECIAL_DEFAULT_TARGET
;
1839 r
= acquire_bus(BUS_MANAGER
, &bus
);
1843 pager_open(arg_no_pager
, false);
1847 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1850 struct machine_info
{
1854 char *control_group
;
1855 uint32_t n_failed_units
;
1860 static const struct bus_properties_map machine_info_property_map
[] = {
1861 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1862 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1863 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1864 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1865 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1869 static void machine_info_clear(struct machine_info
*info
) {
1874 free(info
->control_group
);
1878 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1884 for (i
= 0; i
< n
; i
++)
1885 machine_info_clear(&machine_infos
[i
]);
1887 free(machine_infos
);
1890 static int compare_machine_info(const void *a
, const void *b
) {
1891 const struct machine_info
*u
= a
, *v
= b
;
1893 if (u
->is_host
!= v
->is_host
)
1894 return u
->is_host
> v
->is_host
? -1 : 1;
1896 return strcasecmp(u
->name
, v
->name
);
1899 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1900 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1906 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1913 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1920 static bool output_show_machine(const char *name
, char **patterns
) {
1921 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1924 static int get_machine_list(
1926 struct machine_info
**_machine_infos
,
1929 struct machine_info
*machine_infos
= NULL
;
1930 _cleanup_strv_free_
char **m
= NULL
;
1931 _cleanup_free_
char *hn
= NULL
;
1936 hn
= gethostname_malloc();
1940 if (output_show_machine(hn
, patterns
)) {
1941 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1944 machine_infos
[c
].is_host
= true;
1945 machine_infos
[c
].name
= hn
;
1948 get_machine_properties(bus
, &machine_infos
[c
]);
1952 r
= sd_get_machine_names(&m
);
1954 return log_error_errno(r
, "Failed to get machine list: %m");
1956 STRV_FOREACH(i
, m
) {
1957 _cleanup_free_
char *class = NULL
;
1959 if (!output_show_machine(*i
, patterns
))
1962 sd_machine_get_class(*i
, &class);
1963 if (!streq_ptr(class, "container"))
1966 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1967 free_machines_list(machine_infos
, c
);
1971 machine_infos
[c
].is_host
= false;
1972 machine_infos
[c
].name
= strdup(*i
);
1973 if (!machine_infos
[c
].name
) {
1974 free_machines_list(machine_infos
, c
);
1978 get_machine_properties(NULL
, &machine_infos
[c
]);
1982 *_machine_infos
= machine_infos
;
1986 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1987 struct machine_info
*m
;
1990 namelen
= sizeof("NAME") - 1,
1991 statelen
= sizeof("STATE") - 1,
1992 failedlen
= sizeof("FAILED") - 1,
1993 jobslen
= sizeof("JOBS") - 1;
1995 assert(machine_infos
|| n
== 0);
1997 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1998 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1999 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
2000 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
2001 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
2003 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
2007 if (!arg_no_legend
) {
2011 printf("%-*s %-*s %-*s %-*s\n",
2014 failedlen
, "FAILED",
2018 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2019 const char *on_state
= "", *off_state
= "";
2020 const char *on_failed
= "", *off_failed
= "";
2021 bool circle
= false;
2023 if (streq_ptr(m
->state
, "degraded")) {
2024 on_state
= ansi_highlight_red();
2025 off_state
= ansi_normal();
2027 } else if (!streq_ptr(m
->state
, "running")) {
2028 on_state
= ansi_highlight_yellow();
2029 off_state
= ansi_normal();
2033 if (m
->n_failed_units
> 0) {
2034 on_failed
= ansi_highlight_red();
2035 off_failed
= ansi_normal();
2037 on_failed
= off_failed
= "";
2040 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
2043 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2044 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
2045 on_state
, statelen
, strna(m
->state
), off_state
,
2046 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2047 jobslen
, m
->n_jobs
);
2049 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2050 namelen
, strna(m
->name
),
2051 on_state
, statelen
, strna(m
->state
), off_state
,
2052 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2053 jobslen
, m
->n_jobs
);
2057 printf("\n%u machines listed.\n", n
);
2060 static int list_machines(int argc
, char *argv
[], void *userdata
) {
2061 struct machine_info
*machine_infos
= NULL
;
2065 if (geteuid() != 0) {
2066 log_error("Must be root.");
2070 r
= acquire_bus(BUS_MANAGER
, &bus
);
2074 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2078 pager_open(arg_no_pager
, false);
2080 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2081 output_machines_list(machine_infos
, r
);
2082 free_machines_list(machine_infos
, r
);
2087 static int get_default(int argc
, char *argv
[], void *userdata
) {
2088 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2089 _cleanup_free_
char *_path
= NULL
;
2093 if (install_client_side()) {
2094 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2096 return log_error_errno(r
, "Failed to get default target: %m");
2101 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2104 r
= acquire_bus(BUS_MANAGER
, &bus
);
2108 r
= sd_bus_call_method(
2110 "org.freedesktop.systemd1",
2111 "/org/freedesktop/systemd1",
2112 "org.freedesktop.systemd1.Manager",
2118 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2120 r
= sd_bus_message_read(reply
, "s", &path
);
2122 return bus_log_parse_error(r
);
2126 printf("%s\n", path
);
2131 static int set_default(int argc
, char *argv
[], void *userdata
) {
2132 _cleanup_free_
char *unit
= NULL
;
2133 UnitFileChange
*changes
= NULL
;
2134 unsigned n_changes
= 0;
2140 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2142 return log_error_errno(r
, "Failed to mangle unit name: %m");
2144 if (install_client_side()) {
2145 r
= unit_file_set_default(arg_scope
, UNIT_FILE_FORCE
, arg_root
, unit
, &changes
, &n_changes
);
2146 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2151 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2152 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2155 polkit_agent_open_if_enabled();
2157 r
= acquire_bus(BUS_MANAGER
, &bus
);
2161 r
= sd_bus_call_method(
2163 "org.freedesktop.systemd1",
2164 "/org/freedesktop/systemd1",
2165 "org.freedesktop.systemd1.Manager",
2171 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2173 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2177 /* Try to reload if enabled */
2179 r
= daemon_reload(argc
, argv
, userdata
);
2185 unit_file_changes_free(changes
, n_changes
);
2192 const char *name
, *type
, *state
;
2195 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2196 unsigned id_len
, unit_len
, type_len
, state_len
;
2197 const struct job_info
*j
;
2198 const char *on
, *off
;
2199 bool shorten
= false;
2201 assert(n
== 0 || jobs
);
2204 if (!arg_no_legend
) {
2205 on
= ansi_highlight_green();
2206 off
= ansi_normal();
2208 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2213 pager_open(arg_no_pager
, false);
2215 id_len
= strlen("JOB");
2216 unit_len
= strlen("UNIT");
2217 type_len
= strlen("TYPE");
2218 state_len
= strlen("STATE");
2220 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2221 uint32_t id
= j
->id
;
2222 assert(j
->name
&& j
->type
&& j
->state
);
2224 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2225 unit_len
= MAX(unit_len
, strlen(j
->name
));
2226 type_len
= MAX(type_len
, strlen(j
->type
));
2227 state_len
= MAX(state_len
, strlen(j
->state
));
2230 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2231 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2236 printf("%*s %-*s %-*s %-*s\n",
2240 state_len
, "STATE");
2242 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2243 _cleanup_free_
char *e
= NULL
;
2245 if (streq(j
->state
, "running")) {
2246 on
= ansi_highlight();
2247 off
= ansi_normal();
2251 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2252 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2254 on
, unit_len
, e
? e
: j
->name
, off
,
2256 on
, state_len
, j
->state
, off
);
2259 if (!arg_no_legend
) {
2260 on
= ansi_highlight();
2261 off
= ansi_normal();
2263 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2267 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2268 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2271 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2272 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2273 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2274 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2275 _cleanup_free_
struct job_info
*jobs
= NULL
;
2281 bool skipped
= false;
2283 r
= acquire_bus(BUS_MANAGER
, &bus
);
2287 r
= sd_bus_call_method(
2289 "org.freedesktop.systemd1",
2290 "/org/freedesktop/systemd1",
2291 "org.freedesktop.systemd1.Manager",
2297 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2299 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2301 return bus_log_parse_error(r
);
2303 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2304 struct job_info job
= { id
, name
, type
, state
};
2306 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2311 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2317 return bus_log_parse_error(r
);
2319 r
= sd_bus_message_exit_container(reply
);
2321 return bus_log_parse_error(r
);
2323 pager_open(arg_no_pager
, false);
2325 output_jobs_list(jobs
, c
, skipped
);
2329 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2335 return trivial_method(argc
, argv
, userdata
);
2337 r
= acquire_bus(BUS_MANAGER
, &bus
);
2341 polkit_agent_open_if_enabled();
2343 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2344 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2348 q
= safe_atou32(*name
, &id
);
2350 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2352 q
= sd_bus_call_method(
2354 "org.freedesktop.systemd1",
2355 "/org/freedesktop/systemd1",
2356 "org.freedesktop.systemd1.Manager",
2362 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2371 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2372 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2376 /* We ignore all errors here, since this is used to show a
2379 /* We don't use unit_dbus_path_from_name() directly since we
2380 * don't want to load the unit if it isn't loaded. */
2382 r
= sd_bus_call_method(
2384 "org.freedesktop.systemd1",
2385 "/org/freedesktop/systemd1",
2386 "org.freedesktop.systemd1.Manager",
2394 r
= sd_bus_message_read(reply
, "o", &path
);
2398 r
= sd_bus_get_property_trivial(
2400 "org.freedesktop.systemd1",
2402 "org.freedesktop.systemd1.Unit",
2412 static void warn_unit_file_changed(const char *name
) {
2415 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2416 ansi_highlight_red(),
2419 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2422 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2429 STRV_FOREACH(p
, lp
->search_path
) {
2430 _cleanup_free_
char *path
;
2432 path
= path_join(arg_root
, *p
, unit_name
);
2436 if (access(path
, F_OK
) == 0) {
2446 static int unit_find_paths(
2448 const char *unit_name
,
2450 char **fragment_path
,
2451 char ***dropin_paths
) {
2453 _cleanup_free_
char *path
= NULL
;
2454 _cleanup_strv_free_
char **dropins
= NULL
;
2458 * Finds where the unit is defined on disk. Returns 0 if the unit
2459 * is not found. Returns 1 if it is found, and sets
2460 * - the path to the unit in *path, if it exists on disk,
2461 * - and a strv of existing drop-ins in *dropins,
2462 * if the arg is not NULL and any dropins were found.
2466 assert(fragment_path
);
2469 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2470 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2471 _cleanup_free_
char *unit
= NULL
;
2473 unit
= unit_dbus_path_from_name(unit_name
);
2477 r
= sd_bus_get_property_string(
2479 "org.freedesktop.systemd1",
2481 "org.freedesktop.systemd1.Unit",
2486 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2489 r
= sd_bus_get_property_strv(
2491 "org.freedesktop.systemd1",
2493 "org.freedesktop.systemd1.Unit",
2498 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2501 _cleanup_set_free_ Set
*names
;
2503 names
= set_new(NULL
);
2507 r
= set_put(names
, unit_name
);
2509 return log_error_errno(r
, "Failed to add unit name: %m");
2511 r
= unit_file_find_path(lp
, unit_name
, &path
);
2516 _cleanup_free_
char *template = NULL
;
2518 r
= unit_name_template(unit_name
, &template);
2519 if (r
< 0 && r
!= -EINVAL
)
2520 return log_error_errno(r
, "Failed to determine template name: %m");
2522 r
= unit_file_find_path(lp
, template, &path
);
2529 r
= unit_file_find_dropin_paths(lp
->search_path
, NULL
, names
, &dropins
);
2537 if (!isempty(path
)) {
2538 *fragment_path
= path
;
2543 if (dropin_paths
&& !strv_isempty(dropins
)) {
2544 *dropin_paths
= dropins
;
2549 if (r
== 0 && !arg_force
)
2550 log_error("No files found for %s.", unit_name
);
2555 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2556 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2557 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2558 _cleanup_free_
char *buf
= NULL
;
2559 UnitActiveState state
;
2564 assert(active_state
);
2566 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2568 r
= sd_bus_call_method(
2570 "org.freedesktop.systemd1",
2571 "/org/freedesktop/systemd1",
2572 "org.freedesktop.systemd1.Manager",
2578 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2579 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2581 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2582 * considered inactive. */
2583 state
= UNIT_INACTIVE
;
2586 r
= sd_bus_message_read(reply
, "o", &path
);
2588 return bus_log_parse_error(r
);
2590 r
= sd_bus_get_property_string(
2592 "org.freedesktop.systemd1",
2594 "org.freedesktop.systemd1.Unit",
2599 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2601 state
= unit_active_state_from_string(buf
);
2602 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2603 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2608 *active_state
= state
;
2612 static int check_triggering_units(
2616 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2617 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2618 _cleanup_strv_free_
char **triggered_by
= NULL
;
2619 bool print_warning_label
= true;
2620 UnitActiveState active_state
;
2624 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2626 return log_error_errno(r
, "Failed to mangle unit name: %m");
2628 path
= unit_dbus_path_from_name(n
);
2632 r
= sd_bus_get_property_string(
2634 "org.freedesktop.systemd1",
2636 "org.freedesktop.systemd1.Unit",
2641 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2643 if (streq(load_state
, "masked"))
2646 r
= sd_bus_get_property_strv(
2648 "org.freedesktop.systemd1",
2650 "org.freedesktop.systemd1.Unit",
2655 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2657 STRV_FOREACH(i
, triggered_by
) {
2658 r
= get_state_one_unit(bus
, *i
, &active_state
);
2662 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2665 if (print_warning_label
) {
2666 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2667 print_warning_label
= false;
2670 log_warning(" %s", *i
);
2676 static const struct {
2679 } unit_actions
[] = {
2680 { "start", "StartUnit" },
2681 { "stop", "StopUnit" },
2682 { "condstop", "StopUnit" },
2683 { "reload", "ReloadUnit" },
2684 { "restart", "RestartUnit" },
2685 { "try-restart", "TryRestartUnit" },
2686 { "condrestart", "TryRestartUnit" },
2687 { "reload-or-restart", "ReloadOrRestartUnit" },
2688 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2689 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2690 { "condreload", "ReloadOrTryRestartUnit" },
2691 { "force-reload", "ReloadOrTryRestartUnit" }
2694 static const char *verb_to_method(const char *verb
) {
2697 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2698 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2699 return unit_actions
[i
].method
;
2704 static const char *method_to_verb(const char *method
) {
2707 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2708 if (streq_ptr(unit_actions
[i
].method
, method
))
2709 return unit_actions
[i
].verb
;
2721 static void wait_context_free(WaitContext
*c
) {
2722 c
->match
= sd_bus_slot_unref(c
->match
);
2723 c
->event
= sd_event_unref(c
->event
);
2724 c
->unit_paths
= set_free_free(c
->unit_paths
);
2727 static int on_properties_changed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
2728 WaitContext
*c
= userdata
;
2732 path
= sd_bus_message_get_path(m
);
2733 if (!set_contains(c
->unit_paths
, path
))
2736 /* Check if ActiveState changed to inactive/failed */
2737 /* (s interface, a{sv} changed_properties, as invalidated_properties) */
2738 r
= sd_bus_message_skip(m
, "s");
2740 return bus_log_parse_error(r
);
2742 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
2744 return bus_log_parse_error(r
);
2746 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
2749 r
= sd_bus_message_read(m
, "s", &s
);
2751 return bus_log_parse_error(r
);
2753 if (streq(s
, "ActiveState")) {
2756 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, "s");
2758 return bus_log_parse_error(r
);
2760 r
= sd_bus_message_read(m
, "s", &s
);
2762 return bus_log_parse_error(r
);
2764 is_failed
= streq(s
, "failed");
2765 if (streq(s
, "inactive") || is_failed
) {
2766 log_debug("%s became %s, dropping from --wait tracking", path
, s
);
2767 free(set_remove(c
->unit_paths
, path
));
2768 c
->any_failed
= c
->any_failed
|| is_failed
;
2770 log_debug("ActiveState on %s changed to %s", path
, s
);
2772 break; /* no need to dissect the rest of the message */
2774 /* other property */
2775 r
= sd_bus_message_skip(m
, "v");
2777 return bus_log_parse_error(r
);
2779 r
= sd_bus_message_exit_container(m
);
2781 return bus_log_parse_error(r
);
2784 return bus_log_parse_error(r
);
2786 if (set_isempty(c
->unit_paths
))
2787 sd_event_exit(c
->event
, EXIT_SUCCESS
);
2792 static int start_unit_one(
2797 sd_bus_error
*error
,
2799 WaitContext
*wait_context
) {
2801 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2811 _cleanup_free_
char *unit_path
= NULL
;
2814 log_debug("Watching for property changes of %s", name
);
2815 r
= sd_bus_call_method(
2817 "org.freedesktop.systemd1",
2818 "/org/freedesktop/systemd1",
2819 "org.freedesktop.systemd1.Manager",
2825 return log_error_errno(r
, "Failed to RefUnit %s: %s", name
, bus_error_message(error
, r
));
2827 unit_path
= unit_dbus_path_from_name(name
);
2831 r
= set_put_strdup(wait_context
->unit_paths
, unit_path
);
2833 return log_error_errno(r
, "Failed to add unit path %s to set: %m", unit_path
);
2835 mt
= strjoina("type='signal',"
2836 "interface='org.freedesktop.DBus.Properties',"
2837 "path='", unit_path
, "',"
2838 "member='PropertiesChanged'");
2839 r
= sd_bus_add_match(bus
, &wait_context
->match
, mt
, on_properties_changed
, wait_context
);
2841 return log_error_errno(r
, "Failed to add match for PropertiesChanged signal: %m");
2844 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2846 r
= sd_bus_call_method(
2848 "org.freedesktop.systemd1",
2849 "/org/freedesktop/systemd1",
2850 "org.freedesktop.systemd1.Manager",
2858 /* There's always a fallback possible for legacy actions. */
2859 if (arg_action
!= ACTION_SYSTEMCTL
)
2862 verb
= method_to_verb(method
);
2864 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2866 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2867 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2868 log_error("See %s logs and 'systemctl%s status%s %s' for details.",
2869 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2870 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2871 name
[0] == '-' ? " --" : "",
2877 r
= sd_bus_message_read(reply
, "o", &path
);
2879 return bus_log_parse_error(r
);
2881 if (need_daemon_reload(bus
, name
) > 0)
2882 warn_unit_file_changed(name
);
2885 log_debug("Adding %s to the set", path
);
2886 r
= bus_wait_for_jobs_add(w
, path
);
2894 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2895 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2902 STRV_FOREACH(name
, names
) {
2906 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2908 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2910 return log_error_errno(r
, "Failed to mangle name: %m");
2912 if (string_is_glob(t
))
2913 r
= strv_consume(&globs
, t
);
2915 r
= strv_consume(&mangled
, t
);
2920 /* Query the manager only if any of the names are a glob, since
2921 * this is fairly expensive */
2922 if (!strv_isempty(globs
)) {
2923 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2924 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2925 size_t allocated
, n
;
2927 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2931 n
= strv_length(mangled
);
2934 for (i
= 0; i
< r
; i
++) {
2935 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2938 mangled
[n
] = strdup(unit_infos
[i
].id
);
2942 mangled
[++n
] = NULL
;
2947 mangled
= NULL
; /* do not free */
2952 static const struct {
2956 } action_table
[_ACTION_MAX
] = {
2957 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2958 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2959 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2960 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2961 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2962 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2963 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2964 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2965 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2966 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2967 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2968 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2969 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2970 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2971 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2974 static enum action
verb_to_action(const char *verb
) {
2977 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2978 if (streq_ptr(action_table
[i
].verb
, verb
))
2981 return _ACTION_INVALID
;
2984 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2985 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2986 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2987 _cleanup_strv_free_
char **names
= NULL
;
2989 _cleanup_(wait_context_free
) WaitContext wait_context
= {};
2993 if (arg_wait
&& !strstr(argv
[0], "start")) {
2994 log_error("--wait may only be used with a command that starts units.");
2998 /* we cannot do sender tracking on the private bus, so we need the full
2999 * one for RefUnit to implement --wait */
3000 r
= acquire_bus(arg_wait
? BUS_FULL
: BUS_MANAGER
, &bus
);
3004 ask_password_agent_open_if_enabled();
3005 polkit_agent_open_if_enabled();
3007 if (arg_action
== ACTION_SYSTEMCTL
) {
3010 method
= verb_to_method(argv
[0]);
3011 action
= verb_to_action(argv
[0]);
3013 if (streq(argv
[0], "isolate")) {
3017 mode
= action_table
[action
].mode
?: arg_job_mode
;
3019 one_name
= action_table
[action
].target
;
3021 assert(arg_action
< ELEMENTSOF(action_table
));
3022 assert(action_table
[arg_action
].target
);
3024 method
= "StartUnit";
3026 mode
= action_table
[arg_action
].mode
;
3027 one_name
= action_table
[arg_action
].target
;
3031 names
= strv_new(one_name
, NULL
);
3033 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
3035 return log_error_errno(r
, "Failed to expand names: %m");
3038 if (!arg_no_block
) {
3039 r
= bus_wait_for_jobs_new(bus
, &w
);
3041 return log_error_errno(r
, "Could not watch jobs: %m");
3045 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3047 wait_context
.unit_paths
= set_new(&string_hash_ops
);
3048 if (!wait_context
.unit_paths
)
3051 r
= sd_bus_call_method(
3053 "org.freedesktop.systemd1",
3054 "/org/freedesktop/systemd1",
3055 "org.freedesktop.systemd1.Manager",
3060 return log_error_errno(r
, "Failed to enable subscription: %s", bus_error_message(&error
, r
));
3061 r
= sd_event_default(&wait_context
.event
);
3063 return log_error_errno(r
, "Failed to allocate event loop: %m");
3064 r
= sd_bus_attach_event(bus
, wait_context
.event
, 0);
3066 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
3069 STRV_FOREACH(name
, names
) {
3070 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3073 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
, arg_wait
? &wait_context
: NULL
);
3074 if (r
>= 0 && q
< 0)
3075 r
= translate_bus_error_to_exit_status(q
, &error
);
3078 if (!arg_no_block
) {
3079 int q
, arg_count
= 0;
3080 const char* extra_args
[4] = {};
3082 if (arg_scope
!= UNIT_FILE_SYSTEM
)
3083 extra_args
[arg_count
++] = "--user";
3085 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
3086 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
3087 extra_args
[arg_count
++] = "-H";
3088 extra_args
[arg_count
++] = arg_host
;
3089 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
3090 extra_args
[arg_count
++] = "-M";
3091 extra_args
[arg_count
++] = arg_host
;
3094 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
3098 /* When stopping units, warn if they can still be triggered by
3099 * another active unit (socket, path, timer) */
3100 if (!arg_quiet
&& streq(method
, "StopUnit"))
3101 STRV_FOREACH(name
, names
)
3102 check_triggering_units(bus
, *name
);
3105 if (r
>= 0 && arg_wait
) {
3107 q
= sd_event_loop(wait_context
.event
);
3109 return log_error_errno(q
, "Failed to run event loop: %m");
3110 if (wait_context
.any_failed
)
3117 static int logind_set_wall_message(void) {
3119 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3121 _cleanup_free_
char *m
= NULL
;
3124 r
= acquire_bus(BUS_FULL
, &bus
);
3128 m
= strv_join(arg_wall
, " ");
3132 r
= sd_bus_call_method(
3134 "org.freedesktop.login1",
3135 "/org/freedesktop/login1",
3136 "org.freedesktop.login1.Manager",
3145 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
3151 /* Ask systemd-logind, which might grant access to unprivileged users
3152 * through PolicyKit */
3153 static int logind_reboot(enum action a
) {
3155 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3156 const char *method
, *description
;
3160 r
= acquire_bus(BUS_FULL
, &bus
);
3168 description
= "reboot system";
3171 case ACTION_POWEROFF
:
3172 method
= "PowerOff";
3173 description
= "power off system";
3176 case ACTION_SUSPEND
:
3178 description
= "suspend system";
3181 case ACTION_HIBERNATE
:
3182 method
= "Hibernate";
3183 description
= "hibernate system";
3186 case ACTION_HYBRID_SLEEP
:
3187 method
= "HybridSleep";
3188 description
= "put system into hybrid sleep";
3195 polkit_agent_open_if_enabled();
3196 (void) logind_set_wall_message();
3198 r
= sd_bus_call_method(
3200 "org.freedesktop.login1",
3201 "/org/freedesktop/login1",
3202 "org.freedesktop.login1.Manager",
3206 "b", arg_ask_password
);
3208 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
3216 static int logind_check_inhibitors(enum action a
) {
3218 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3219 _cleanup_strv_free_
char **sessions
= NULL
;
3220 const char *what
, *who
, *why
, *mode
;
3227 if (arg_ignore_inhibitors
|| arg_force
> 0)
3239 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
3242 r
= acquire_bus(BUS_FULL
, &bus
);
3246 r
= sd_bus_call_method(
3248 "org.freedesktop.login1",
3249 "/org/freedesktop/login1",
3250 "org.freedesktop.login1.Manager",
3256 /* If logind is not around, then there are no inhibitors... */
3259 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3261 return bus_log_parse_error(r
);
3263 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3264 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3265 _cleanup_strv_free_
char **sv
= NULL
;
3267 if (!streq(mode
, "block"))
3270 sv
= strv_split(what
, ":");
3274 if ((pid_t
) pid
< 0)
3275 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
3277 if (!strv_contains(sv
,
3282 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3285 get_process_comm(pid
, &comm
);
3286 user
= uid_to_name(uid
);
3288 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3289 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3294 return bus_log_parse_error(r
);
3296 r
= sd_bus_message_exit_container(reply
);
3298 return bus_log_parse_error(r
);
3300 /* Check for current sessions */
3301 sd_get_sessions(&sessions
);
3302 STRV_FOREACH(s
, sessions
) {
3303 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3305 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3308 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3311 if (sd_session_get_type(*s
, &type
) < 0 || !STR_IN_SET(type
, "x11", "tty"))
3314 sd_session_get_tty(*s
, &tty
);
3315 sd_session_get_seat(*s
, &seat
);
3316 sd_session_get_service(*s
, &service
);
3317 user
= uid_to_name(uid
);
3319 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3326 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3327 action_table
[a
].verb
);
3335 static int logind_prepare_firmware_setup(void) {
3337 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3341 r
= acquire_bus(BUS_FULL
, &bus
);
3345 r
= sd_bus_call_method(
3347 "org.freedesktop.login1",
3348 "/org/freedesktop/login1",
3349 "org.freedesktop.login1.Manager",
3350 "SetRebootToFirmwareSetup",
3355 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3359 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3364 static int prepare_firmware_setup(void) {
3367 if (!arg_firmware_setup
)
3370 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3372 r
= efi_set_reboot_to_firmware(true);
3374 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3379 return logind_prepare_firmware_setup();
3382 static int set_exit_code(uint8_t code
) {
3383 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3387 r
= acquire_bus(BUS_MANAGER
, &bus
);
3391 r
= sd_bus_call_method(
3393 "org.freedesktop.systemd1",
3394 "/org/freedesktop/systemd1",
3395 "org.freedesktop.systemd1.Manager",
3401 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3406 static int start_special(int argc
, char *argv
[], void *userdata
) {
3412 a
= verb_to_action(argv
[0]);
3414 r
= logind_check_inhibitors(a
);
3418 if (arg_force
>= 2 && geteuid() != 0) {
3419 log_error("Must be root.");
3423 r
= prepare_firmware_setup();
3427 if (a
== ACTION_REBOOT
&& argc
> 1) {
3428 r
= update_reboot_parameter_and_warn(argv
[1]);
3432 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3435 /* If the exit code is not given on the command line,
3436 * don't reset it to zero: just keep it as it might
3437 * have been set previously. */
3439 r
= safe_atou8(argv
[1], &code
);
3441 return log_error_errno(r
, "Invalid exit code.");
3443 r
= set_exit_code(code
);
3448 if (arg_force
>= 2 &&
3455 if (arg_force
>= 1 &&
3462 return trivial_method(argc
, argv
, userdata
);
3464 /* First try logind, to allow authentication with polkit */
3470 ACTION_HYBRID_SLEEP
)) {
3471 r
= logind_reboot(a
);
3474 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3475 /* requested operation is not supported or already in progress */
3478 /* On all other errors, try low-level operation */
3481 return start_unit(argc
, argv
, userdata
);
3484 static int start_system_special(int argc
, char *argv
[], void *userdata
) {
3485 /* Like start_special above, but raises an error when running in user mode */
3487 if (arg_scope
!= UNIT_FILE_SYSTEM
) {
3488 log_error("Bad action for %s mode.",
3489 arg_scope
== UNIT_FILE_GLOBAL
? "--global" : "--user");
3493 return start_special(argc
, argv
, userdata
);
3496 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3497 _cleanup_strv_free_
char **names
= NULL
;
3498 UnitActiveState active_state
;
3504 r
= acquire_bus(BUS_MANAGER
, &bus
);
3508 r
= expand_names(bus
, args
, NULL
, &names
);
3510 return log_error_errno(r
, "Failed to expand names: %m");
3512 STRV_FOREACH(name
, names
) {
3513 r
= get_state_one_unit(bus
, *name
, &active_state
);
3518 puts(unit_active_state_to_string(active_state
));
3520 for (i
= 0; i
< nb_states
; ++i
)
3521 if (good_states
[i
] == active_state
)
3525 /* use the given return code for the case that we won't find
3526 * any unit which matches the list */
3527 return found
? 0 : code
;
3530 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3531 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3532 /* According to LSB: 3, "program is not running" */
3533 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3536 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3537 const UnitActiveState states
[] = { UNIT_FAILED
};
3538 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3541 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3542 _cleanup_strv_free_
char **names
= NULL
;
3543 char *kill_who
= NULL
, **name
;
3547 r
= acquire_bus(BUS_MANAGER
, &bus
);
3551 polkit_agent_open_if_enabled();
3554 arg_kill_who
= "all";
3556 /* --fail was specified */
3557 if (streq(arg_job_mode
, "fail"))
3558 kill_who
= strjoina(arg_kill_who
, "-fail");
3560 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3562 return log_error_errno(r
, "Failed to expand names: %m");
3564 STRV_FOREACH(name
, names
) {
3565 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3567 q
= sd_bus_call_method(
3569 "org.freedesktop.systemd1",
3570 "/org/freedesktop/systemd1",
3571 "org.freedesktop.systemd1.Manager",
3575 "ssi", *name
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3577 log_error_errno(q
, "Failed to kill unit %s: %s", *name
, bus_error_message(&error
, q
));
3586 typedef struct ExecStatusInfo
{
3594 usec_t start_timestamp
;
3595 usec_t exit_timestamp
;
3600 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3603 static void exec_status_info_free(ExecStatusInfo
*i
) {
3612 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3613 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3616 int32_t code
, status
;
3622 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3624 return bus_log_parse_error(r
);
3628 r
= sd_bus_message_read(m
, "s", &path
);
3630 return bus_log_parse_error(r
);
3632 i
->path
= strdup(path
);
3636 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3638 return bus_log_parse_error(r
);
3640 r
= sd_bus_message_read(m
,
3643 &start_timestamp
, &start_timestamp_monotonic
,
3644 &exit_timestamp
, &exit_timestamp_monotonic
,
3648 return bus_log_parse_error(r
);
3651 i
->start_timestamp
= (usec_t
) start_timestamp
;
3652 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3653 i
->pid
= (pid_t
) pid
;
3657 r
= sd_bus_message_exit_container(m
);
3659 return bus_log_parse_error(r
);
3664 typedef struct UnitCondition
{
3671 LIST_FIELDS(struct UnitCondition
, conditions
);
3674 static void unit_condition_free(UnitCondition
*c
) {
3683 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition
*, unit_condition_free
);
3685 typedef struct UnitStatusInfo
{
3687 const char *load_state
;
3688 const char *active_state
;
3689 const char *sub_state
;
3690 const char *unit_file_state
;
3691 const char *unit_file_preset
;
3693 const char *description
;
3694 const char *following
;
3696 char **documentation
;
3698 const char *fragment_path
;
3699 const char *source_path
;
3700 const char *control_group
;
3702 char **dropin_paths
;
3704 const char *load_error
;
3707 usec_t inactive_exit_timestamp
;
3708 usec_t inactive_exit_timestamp_monotonic
;
3709 usec_t active_enter_timestamp
;
3710 usec_t active_exit_timestamp
;
3711 usec_t inactive_enter_timestamp
;
3713 bool need_daemon_reload
;
3719 const char *status_text
;
3720 const char *pid_file
;
3724 usec_t start_timestamp
;
3725 usec_t exit_timestamp
;
3727 int exit_code
, exit_status
;
3729 usec_t condition_timestamp
;
3730 bool condition_result
;
3731 LIST_HEAD(UnitCondition
, conditions
);
3733 usec_t assert_timestamp
;
3735 bool failed_assert_trigger
;
3736 bool failed_assert_negate
;
3737 const char *failed_assert
;
3738 const char *failed_assert_parameter
;
3741 unsigned n_accepted
;
3742 unsigned n_connections
;
3745 /* Pairs of type, path */
3749 const char *sysfs_path
;
3751 /* Mount, Automount */
3758 uint64_t memory_current
;
3759 uint64_t memory_low
;
3760 uint64_t memory_high
;
3761 uint64_t memory_max
;
3762 uint64_t memory_swap_max
;
3763 uint64_t memory_limit
;
3764 uint64_t cpu_usage_nsec
;
3765 uint64_t tasks_current
;
3768 LIST_HEAD(ExecStatusInfo
, exec
);
3771 static void unit_status_info_free(UnitStatusInfo
*info
) {
3775 strv_free(info
->documentation
);
3776 strv_free(info
->dropin_paths
);
3777 strv_free(info
->listen
);
3779 while ((c
= info
->conditions
)) {
3780 LIST_REMOVE(conditions
, info
->conditions
, c
);
3781 unit_condition_free(c
);
3784 while ((p
= info
->exec
)) {
3785 LIST_REMOVE(exec
, info
->exec
, p
);
3786 exec_status_info_free(p
);
3790 static void print_status_info(
3796 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3798 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3799 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3806 /* This shows pretty information about a unit. See
3807 * print_property() for a low-level property printer */
3809 if (streq_ptr(i
->active_state
, "failed")) {
3810 active_on
= ansi_highlight_red();
3811 active_off
= ansi_normal();
3812 } else if (STRPTR_IN_SET(i
->active_state
, "active", "reloading")) {
3813 active_on
= ansi_highlight_green();
3814 active_off
= ansi_normal();
3816 active_on
= active_off
= "";
3818 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3820 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3821 printf(" - %s", i
->description
);
3826 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3828 if (streq_ptr(i
->load_state
, "error")) {
3829 on
= ansi_highlight_red();
3830 off
= ansi_normal();
3834 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3836 if (i
->load_error
!= 0)
3837 printf(" Loaded: %s%s%s (Reason: %s)\n",
3838 on
, strna(i
->load_state
), off
, i
->load_error
);
3839 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3840 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3841 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3842 else if (path
&& !isempty(i
->unit_file_state
))
3843 printf(" Loaded: %s%s%s (%s; %s)\n",
3844 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3846 printf(" Loaded: %s%s%s (%s)\n",
3847 on
, strna(i
->load_state
), off
, path
);
3849 printf(" Loaded: %s%s%s\n",
3850 on
, strna(i
->load_state
), off
);
3853 printf("Transient: yes\n");
3855 if (!strv_isempty(i
->dropin_paths
)) {
3856 _cleanup_free_
char *dir
= NULL
;
3860 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3861 if (! dir
|| last
) {
3862 printf(dir
? " " : " Drop-In: ");
3866 dir
= dirname_malloc(*dropin
);
3872 printf("%s\n %s", dir
,
3873 special_glyph(TREE_RIGHT
));
3876 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3878 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3882 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3884 printf(" Active: %s%s (%s)%s",
3885 active_on
, strna(i
->active_state
), ss
, active_off
);
3887 printf(" Active: %s%s%s",
3888 active_on
, strna(i
->active_state
), active_off
);
3890 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3891 printf(" (Result: %s)", i
->result
);
3893 timestamp
= STRPTR_IN_SET(i
->active_state
, "active", "reloading") ? i
->active_enter_timestamp
:
3894 STRPTR_IN_SET(i
->active_state
, "inactive", "failed") ? i
->inactive_enter_timestamp
:
3895 STRPTR_IN_SET(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3896 i
->active_exit_timestamp
;
3898 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3899 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3902 printf(" since %s; %s\n", s2
, s1
);
3904 printf(" since %s\n", s2
);
3908 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3912 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3913 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3915 printf("Condition: start %scondition failed%s at %s%s%s\n",
3916 ansi_highlight_yellow(), ansi_normal(),
3917 s2
, s1
? "; " : "", strempty(s1
));
3919 LIST_FOREACH(conditions
, c
, i
->conditions
)
3920 if (c
->tristate
< 0)
3923 LIST_FOREACH(conditions
, c
, i
->conditions
)
3924 if (c
->tristate
< 0)
3925 printf(" %s %s=%s%s%s was not met\n",
3926 --n
? special_glyph(TREE_BRANCH
) : special_glyph(TREE_RIGHT
),
3928 c
->trigger
? "|" : "",
3929 c
->negate
? "!" : "",
3933 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3934 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3935 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3937 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3938 ansi_highlight_red(), ansi_normal(),
3939 s2
, s1
? "; " : "", strempty(s1
));
3940 if (i
->failed_assert_trigger
)
3941 printf(" none of the trigger assertions were met\n");
3942 else if (i
->failed_assert
)
3943 printf(" %s=%s%s was not met\n",
3945 i
->failed_assert_negate
? "!" : "",
3946 i
->failed_assert_parameter
);
3950 printf(" Device: %s\n", i
->sysfs_path
);
3952 printf(" Where: %s\n", i
->where
);
3954 printf(" What: %s\n", i
->what
);
3956 STRV_FOREACH(t
, i
->documentation
)
3957 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3959 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3960 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3963 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3965 LIST_FOREACH(exec
, p
, i
->exec
) {
3966 _cleanup_free_
char *argv
= NULL
;
3969 /* Only show exited processes here */
3973 argv
= strv_join(p
->argv
, " ");
3974 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3976 good
= is_clean_exit(p
->code
, p
->status
, EXIT_CLEAN_DAEMON
, NULL
);
3978 on
= ansi_highlight_red();
3979 off
= ansi_normal();
3983 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3985 if (p
->code
== CLD_EXITED
) {
3988 printf("status=%i", p
->status
);
3990 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3995 printf("signal=%s", signal_to_string(p
->status
));
3997 printf(")%s\n", off
);
3999 if (i
->main_pid
== p
->pid
&&
4000 i
->start_timestamp
== p
->start_timestamp
&&
4001 i
->exit_timestamp
== p
->start_timestamp
)
4002 /* Let's not show this twice */
4005 if (p
->pid
== i
->control_pid
)
4009 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
4010 if (i
->main_pid
> 0) {
4011 printf(" Main PID: "PID_FMT
, i
->main_pid
);
4014 _cleanup_free_
char *comm
= NULL
;
4015 (void) get_process_comm(i
->main_pid
, &comm
);
4017 printf(" (%s)", comm
);
4018 } else if (i
->exit_code
> 0) {
4019 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
4021 if (i
->exit_code
== CLD_EXITED
) {
4024 printf("status=%i", i
->exit_status
);
4026 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
4031 printf("signal=%s", signal_to_string(i
->exit_status
));
4036 if (i
->control_pid
> 0) {
4037 _cleanup_free_
char *c
= NULL
;
4039 if (i
->main_pid
> 0)
4040 fputs("; Control PID: ", stdout
);
4042 fputs("Cntrl PID: ", stdout
); /* if first in column, abbreviated so it fits alignment */
4044 printf(PID_FMT
, i
->control_pid
);
4046 (void) get_process_comm(i
->control_pid
, &c
);
4055 printf(" Status: \"%s\"\n", i
->status_text
);
4056 if (i
->status_errno
> 0)
4057 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
4059 if (i
->tasks_current
!= (uint64_t) -1) {
4060 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
4062 if (i
->tasks_max
!= (uint64_t) -1)
4063 printf(" (limit: %" PRIu64
")\n", i
->tasks_max
);
4068 if (i
->memory_current
!= (uint64_t) -1) {
4069 char buf
[FORMAT_BYTES_MAX
];
4071 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
4073 if (i
->memory_low
> 0 || i
->memory_high
!= CGROUP_LIMIT_MAX
||
4074 i
->memory_max
!= CGROUP_LIMIT_MAX
|| i
->memory_swap_max
!= CGROUP_LIMIT_MAX
||
4075 i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4076 const char *prefix
= "";
4079 if (i
->memory_low
> 0) {
4080 printf("%slow: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_low
));
4083 if (i
->memory_high
!= CGROUP_LIMIT_MAX
) {
4084 printf("%shigh: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_high
));
4087 if (i
->memory_max
!= CGROUP_LIMIT_MAX
) {
4088 printf("%smax: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_max
));
4091 if (i
->memory_swap_max
!= CGROUP_LIMIT_MAX
) {
4092 printf("%sswap max: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_swap_max
));
4095 if (i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4096 printf("%slimit: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
4104 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
4105 char buf
[FORMAT_TIMESPAN_MAX
];
4106 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
4109 if (i
->control_group
) {
4110 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4111 static const char prefix
[] = " ";
4114 printf(" CGroup: %s\n", i
->control_group
);
4117 if (c
> sizeof(prefix
) - 1)
4118 c
-= sizeof(prefix
) - 1;
4122 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
4127 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4129 if (i
->main_pid
> 0)
4130 extra
[k
++] = i
->main_pid
;
4132 if (i
->control_pid
> 0)
4133 extra
[k
++] = i
->control_pid
;
4135 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
4137 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
4140 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
4141 show_journal_by_unit(
4146 i
->inactive_exit_timestamp_monotonic
,
4149 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
4150 SD_JOURNAL_LOCAL_ONLY
,
4151 arg_scope
== UNIT_FILE_SYSTEM
,
4154 if (i
->need_daemon_reload
)
4155 warn_unit_file_changed(i
->id
);
4158 static void show_unit_help(UnitStatusInfo
*i
) {
4163 if (!i
->documentation
) {
4164 log_info("Documentation for %s not known.", i
->id
);
4168 STRV_FOREACH(p
, i
->documentation
)
4169 if (startswith(*p
, "man:"))
4170 show_man_page(*p
+ 4, false);
4172 log_info("Can't show: %s", *p
);
4175 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
4182 switch (contents
[0]) {
4184 case SD_BUS_TYPE_STRING
: {
4187 r
= sd_bus_message_read(m
, "s", &s
);
4189 return bus_log_parse_error(r
);
4192 if (streq(name
, "Id"))
4194 else if (streq(name
, "LoadState"))
4196 else if (streq(name
, "ActiveState"))
4197 i
->active_state
= s
;
4198 else if (streq(name
, "SubState"))
4200 else if (streq(name
, "Description"))
4202 else if (streq(name
, "FragmentPath"))
4203 i
->fragment_path
= s
;
4204 else if (streq(name
, "SourcePath"))
4207 else if (streq(name
, "DefaultControlGroup")) {
4209 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
4211 i
->control_group
= e
;
4214 else if (streq(name
, "ControlGroup"))
4215 i
->control_group
= s
;
4216 else if (streq(name
, "StatusText"))
4218 else if (streq(name
, "PIDFile"))
4220 else if (streq(name
, "SysFSPath"))
4222 else if (streq(name
, "Where"))
4224 else if (streq(name
, "What"))
4226 else if (streq(name
, "Following"))
4228 else if (streq(name
, "UnitFileState"))
4229 i
->unit_file_state
= s
;
4230 else if (streq(name
, "UnitFilePreset"))
4231 i
->unit_file_preset
= s
;
4232 else if (streq(name
, "Result"))
4239 case SD_BUS_TYPE_BOOLEAN
: {
4242 r
= sd_bus_message_read(m
, "b", &b
);
4244 return bus_log_parse_error(r
);
4246 if (streq(name
, "Accept"))
4248 else if (streq(name
, "NeedDaemonReload"))
4249 i
->need_daemon_reload
= b
;
4250 else if (streq(name
, "ConditionResult"))
4251 i
->condition_result
= b
;
4252 else if (streq(name
, "AssertResult"))
4253 i
->assert_result
= b
;
4254 else if (streq(name
, "Transient"))
4260 case SD_BUS_TYPE_UINT32
: {
4263 r
= sd_bus_message_read(m
, "u", &u
);
4265 return bus_log_parse_error(r
);
4267 if (streq(name
, "MainPID")) {
4269 i
->main_pid
= (pid_t
) u
;
4272 } else if (streq(name
, "ControlPID"))
4273 i
->control_pid
= (pid_t
) u
;
4274 else if (streq(name
, "ExecMainPID")) {
4276 i
->main_pid
= (pid_t
) u
;
4277 } else if (streq(name
, "NAccepted"))
4279 else if (streq(name
, "NConnections"))
4280 i
->n_connections
= u
;
4285 case SD_BUS_TYPE_INT32
: {
4288 r
= sd_bus_message_read(m
, "i", &j
);
4290 return bus_log_parse_error(r
);
4292 if (streq(name
, "ExecMainCode"))
4293 i
->exit_code
= (int) j
;
4294 else if (streq(name
, "ExecMainStatus"))
4295 i
->exit_status
= (int) j
;
4296 else if (streq(name
, "StatusErrno"))
4297 i
->status_errno
= (int) j
;
4302 case SD_BUS_TYPE_UINT64
: {
4305 r
= sd_bus_message_read(m
, "t", &u
);
4307 return bus_log_parse_error(r
);
4309 if (streq(name
, "ExecMainStartTimestamp"))
4310 i
->start_timestamp
= (usec_t
) u
;
4311 else if (streq(name
, "ExecMainExitTimestamp"))
4312 i
->exit_timestamp
= (usec_t
) u
;
4313 else if (streq(name
, "ActiveEnterTimestamp"))
4314 i
->active_enter_timestamp
= (usec_t
) u
;
4315 else if (streq(name
, "InactiveEnterTimestamp"))
4316 i
->inactive_enter_timestamp
= (usec_t
) u
;
4317 else if (streq(name
, "InactiveExitTimestamp"))
4318 i
->inactive_exit_timestamp
= (usec_t
) u
;
4319 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4320 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4321 else if (streq(name
, "ActiveExitTimestamp"))
4322 i
->active_exit_timestamp
= (usec_t
) u
;
4323 else if (streq(name
, "ConditionTimestamp"))
4324 i
->condition_timestamp
= (usec_t
) u
;
4325 else if (streq(name
, "AssertTimestamp"))
4326 i
->assert_timestamp
= (usec_t
) u
;
4327 else if (streq(name
, "MemoryCurrent"))
4328 i
->memory_current
= u
;
4329 else if (streq(name
, "MemoryLow"))
4331 else if (streq(name
, "MemoryHigh"))
4333 else if (streq(name
, "MemoryMax"))
4335 else if (streq(name
, "MemorySwapMax"))
4336 i
->memory_swap_max
= u
;
4337 else if (streq(name
, "MemoryLimit"))
4338 i
->memory_limit
= u
;
4339 else if (streq(name
, "TasksCurrent"))
4340 i
->tasks_current
= u
;
4341 else if (streq(name
, "TasksMax"))
4343 else if (streq(name
, "CPUUsageNSec"))
4344 i
->cpu_usage_nsec
= u
;
4349 case SD_BUS_TYPE_ARRAY
:
4351 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4352 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4354 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4356 return bus_log_parse_error(r
);
4358 info
= new0(ExecStatusInfo
, 1);
4362 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4364 info
->name
= strdup(name
);
4368 LIST_PREPEND(exec
, i
->exec
, info
);
4370 info
= new0(ExecStatusInfo
, 1);
4376 return bus_log_parse_error(r
);
4378 r
= sd_bus_message_exit_container(m
);
4380 return bus_log_parse_error(r
);
4384 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4385 const char *type
, *path
;
4387 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4389 return bus_log_parse_error(r
);
4391 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4393 r
= strv_extend(&i
->listen
, type
);
4397 r
= strv_extend(&i
->listen
, path
);
4402 return bus_log_parse_error(r
);
4404 r
= sd_bus_message_exit_container(m
);
4406 return bus_log_parse_error(r
);
4410 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4412 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4414 return bus_log_parse_error(r
);
4416 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4418 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4420 return bus_log_parse_error(r
);
4422 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4423 const char *cond
, *param
;
4424 int trigger
, negate
;
4427 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4429 return bus_log_parse_error(r
);
4431 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4432 _cleanup_(unit_condition_freep
) UnitCondition
*c
= NULL
;
4434 log_debug("%s trigger=%d negate=%d %s →%d", cond
, trigger
, negate
, param
, state
);
4436 c
= new0(UnitCondition
, 1);
4440 c
->name
= strdup(cond
);
4441 c
->param
= strdup(param
);
4442 if (!c
->name
|| !c
->param
)
4445 c
->trigger
= trigger
;
4447 c
->tristate
= state
;
4449 LIST_PREPEND(conditions
, i
->conditions
, c
);
4453 return bus_log_parse_error(r
);
4455 r
= sd_bus_message_exit_container(m
);
4457 return bus_log_parse_error(r
);
4459 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4460 const char *cond
, *param
;
4461 int trigger
, negate
;
4464 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4466 return bus_log_parse_error(r
);
4468 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4469 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4470 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4471 i
->failed_assert
= cond
;
4472 i
->failed_assert_trigger
= trigger
;
4473 i
->failed_assert_negate
= negate
;
4474 i
->failed_assert_parameter
= param
;
4478 return bus_log_parse_error(r
);
4480 r
= sd_bus_message_exit_container(m
);
4482 return bus_log_parse_error(r
);
4489 case SD_BUS_TYPE_STRUCT_BEGIN
:
4491 if (streq(name
, "LoadError")) {
4492 const char *n
, *message
;
4494 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4496 return bus_log_parse_error(r
);
4498 if (!isempty(message
))
4499 i
->load_error
= message
;
4512 r
= sd_bus_message_skip(m
, contents
);
4514 return bus_log_parse_error(r
);
4519 #define print_prop(name, fmt, ...) \
4522 printf(fmt "\n", __VA_ARGS__); \
4524 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4527 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4533 /* This is a low-level property printer, see
4534 * print_status_info() for the nicer output */
4536 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4537 /* skip what we didn't read */
4538 r
= sd_bus_message_skip(m
, contents
);
4542 switch (contents
[0]) {
4544 case SD_BUS_TYPE_STRUCT_BEGIN
:
4546 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4549 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4551 return bus_log_parse_error(r
);
4554 print_prop(name
, "%"PRIu32
, u
);
4556 print_prop(name
, "%s", "");
4560 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4563 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4565 return bus_log_parse_error(r
);
4567 if (arg_all
|| !isempty(s
))
4568 print_prop(name
, "%s", s
);
4572 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4573 const char *a
= NULL
, *b
= NULL
;
4575 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4577 return bus_log_parse_error(r
);
4579 if (arg_all
|| !isempty(a
) || !isempty(b
))
4580 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4583 } else if (streq_ptr(name
, "SystemCallFilter")) {
4584 _cleanup_strv_free_
char **l
= NULL
;
4587 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4589 return bus_log_parse_error(r
);
4591 r
= sd_bus_message_read(m
, "b", &whitelist
);
4593 return bus_log_parse_error(r
);
4595 r
= sd_bus_message_read_strv(m
, &l
);
4597 return bus_log_parse_error(r
);
4599 r
= sd_bus_message_exit_container(m
);
4601 return bus_log_parse_error(r
);
4603 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4608 fputs(name
, stdout
);
4615 STRV_FOREACH(i
, l
) {
4623 fputc('\n', stdout
);
4631 case SD_BUS_TYPE_ARRAY
:
4633 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4637 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4639 return bus_log_parse_error(r
);
4641 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4642 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path
, yes_no(ignore
));
4645 return bus_log_parse_error(r
);
4647 r
= sd_bus_message_exit_container(m
);
4649 return bus_log_parse_error(r
);
4653 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4654 const char *type
, *path
;
4656 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4658 return bus_log_parse_error(r
);
4660 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4661 print_prop(type
, "%s", path
);
4663 return bus_log_parse_error(r
);
4665 r
= sd_bus_message_exit_container(m
);
4667 return bus_log_parse_error(r
);
4671 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4672 const char *type
, *path
;
4674 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4676 return bus_log_parse_error(r
);
4678 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4682 printf("Listen%s=%s\n", type
, path
);
4684 return bus_log_parse_error(r
);
4686 r
= sd_bus_message_exit_container(m
);
4688 return bus_log_parse_error(r
);
4692 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4694 uint64_t value
, next_elapse
;
4696 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4698 return bus_log_parse_error(r
);
4700 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4701 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4703 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4704 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4705 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4708 return bus_log_parse_error(r
);
4710 r
= sd_bus_message_exit_container(m
);
4712 return bus_log_parse_error(r
);
4716 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4717 ExecStatusInfo info
= {};
4719 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4721 return bus_log_parse_error(r
);
4723 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4724 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4725 _cleanup_free_
char *tt
;
4727 tt
= strv_join(info
.argv
, " ");
4730 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4733 yes_no(info
.ignore
),
4734 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4735 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4737 sigchld_code_to_string(info
.code
),
4739 info
.code
== CLD_EXITED
? "" : "/",
4740 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4743 strv_free(info
.argv
);
4747 r
= sd_bus_message_exit_container(m
);
4749 return bus_log_parse_error(r
);
4753 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4754 const char *path
, *rwm
;
4756 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4758 return bus_log_parse_error(r
);
4760 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4761 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4763 return bus_log_parse_error(r
);
4765 r
= sd_bus_message_exit_container(m
);
4767 return bus_log_parse_error(r
);
4771 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4772 STR_IN_SET(name
, "IODeviceWeight", "BlockIODeviceWeight")) {
4776 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4778 return bus_log_parse_error(r
);
4780 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4781 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4783 return bus_log_parse_error(r
);
4785 r
= sd_bus_message_exit_container(m
);
4787 return bus_log_parse_error(r
);
4791 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4792 (cgroup_io_limit_type_from_string(name
) >= 0 ||
4793 STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
4797 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4799 return bus_log_parse_error(r
);
4801 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4802 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4804 return bus_log_parse_error(r
);
4806 r
= sd_bus_message_exit_container(m
);
4808 return bus_log_parse_error(r
);
4816 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4818 return bus_log_parse_error(r
);
4821 r
= sd_bus_message_skip(m
, contents
);
4823 return bus_log_parse_error(r
);
4826 printf("%s=[unprintable]\n", name
);
4832 static int show_one(
4837 bool show_properties
,
4841 static const struct bus_properties_map property_map
[] = {
4842 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
4843 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
) },
4847 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4848 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4849 _cleanup_set_free_ Set
*found_properties
= NULL
;
4850 _cleanup_(unit_status_info_free
) UnitStatusInfo info
= {
4851 .memory_current
= (uint64_t) -1,
4852 .memory_high
= CGROUP_LIMIT_MAX
,
4853 .memory_max
= CGROUP_LIMIT_MAX
,
4854 .memory_swap_max
= CGROUP_LIMIT_MAX
,
4855 .memory_limit
= (uint64_t) -1,
4856 .cpu_usage_nsec
= (uint64_t) -1,
4857 .tasks_current
= (uint64_t) -1,
4858 .tasks_max
= (uint64_t) -1,
4865 log_debug("Showing one %s", path
);
4867 r
= sd_bus_call_method(
4869 "org.freedesktop.systemd1",
4871 "org.freedesktop.DBus.Properties",
4877 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4880 r
= bus_message_map_all_properties(reply
, property_map
, &info
);
4882 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
4884 if (streq_ptr(info
.load_state
, "not-found") && streq_ptr(info
.active_state
, "inactive")) {
4885 log_full(streq(verb
, "status") ? LOG_ERR
: LOG_DEBUG
,
4886 "Unit %s could not be found.", unit
);
4888 if (streq(verb
, "status"))
4889 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
;
4891 if (!streq(verb
, "show"))
4895 r
= sd_bus_message_rewind(reply
, true);
4897 return log_error_errno(r
, "Failed to rewind: %s", bus_error_message(&error
, r
));
4900 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4902 return bus_log_parse_error(r
);
4909 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4910 const char *name
, *contents
;
4912 r
= sd_bus_message_read(reply
, "s", &name
);
4914 return bus_log_parse_error(r
);
4916 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4918 return bus_log_parse_error(r
);
4920 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4922 return bus_log_parse_error(r
);
4924 if (show_properties
) {
4925 r
= set_ensure_allocated(&found_properties
, &string_hash_ops
);
4929 r
= set_put(found_properties
, name
);
4930 if (r
< 0 && r
!= EEXIST
)
4933 r
= print_property(name
, reply
, contents
);
4935 r
= status_property(name
, reply
, &info
, contents
);
4939 r
= sd_bus_message_exit_container(reply
);
4941 return bus_log_parse_error(r
);
4943 r
= sd_bus_message_exit_container(reply
);
4945 return bus_log_parse_error(r
);
4948 return bus_log_parse_error(r
);
4950 r
= sd_bus_message_exit_container(reply
);
4952 return bus_log_parse_error(r
);
4955 if (show_properties
) {
4957 int not_found_level
= streq(verb
, "show") ? LOG_DEBUG
: LOG_WARNING
;
4959 STRV_FOREACH(pp
, arg_properties
)
4960 if (!set_contains(found_properties
, *pp
)) {
4961 log_full(not_found_level
, "Property %s does not exist.", *pp
);
4965 } else if (streq(verb
, "help"))
4966 show_unit_help(&info
);
4967 else if (streq(verb
, "status")) {
4968 print_status_info(bus
, &info
, ellipsized
);
4970 if (info
.active_state
&& !STR_IN_SET(info
.active_state
, "active", "reloading"))
4971 r
= EXIT_PROGRAM_NOT_RUNNING
;
4973 r
= EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
;
4979 static int get_unit_dbus_path_by_pid(
4984 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4985 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4989 r
= sd_bus_call_method(
4991 "org.freedesktop.systemd1",
4992 "/org/freedesktop/systemd1",
4993 "org.freedesktop.systemd1.Manager",
4999 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
5001 r
= sd_bus_message_read(reply
, "o", &u
);
5003 return bus_log_parse_error(r
);
5013 static int show_all(
5016 bool show_properties
,
5020 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5021 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
5026 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
5030 pager_open(arg_no_pager
, false);
5034 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
5036 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
5037 _cleanup_free_
char *p
= NULL
;
5039 p
= unit_dbus_path_from_name(u
->id
);
5043 r
= show_one(verb
, bus
, p
, u
->id
, show_properties
, new_line
, ellipsized
);
5046 else if (r
> 0 && ret
== 0)
5053 static int show_system_status(sd_bus
*bus
) {
5054 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
5055 _cleanup_free_
char *hn
= NULL
;
5056 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
5057 const char *on
, *off
;
5060 hn
= gethostname_malloc();
5064 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
5066 return log_error_errno(r
, "Failed to read server status: %m");
5068 if (streq_ptr(mi
.state
, "degraded")) {
5069 on
= ansi_highlight_red();
5070 off
= ansi_normal();
5071 } else if (!streq_ptr(mi
.state
, "running")) {
5072 on
= ansi_highlight_yellow();
5073 off
= ansi_normal();
5077 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
5079 printf(" State: %s%s%s\n",
5080 on
, strna(mi
.state
), off
);
5082 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
5083 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
5085 printf(" Since: %s; %s\n",
5086 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
5087 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
5089 printf(" CGroup: %s\n", mi
.control_group
?: "/");
5090 if (IN_SET(arg_transport
,
5091 BUS_TRANSPORT_LOCAL
,
5092 BUS_TRANSPORT_MACHINE
)) {
5093 static const char prefix
[] = " ";
5097 if (c
> sizeof(prefix
) - 1)
5098 c
-= sizeof(prefix
) - 1;
5102 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
5108 static int show(int argc
, char *argv
[], void *userdata
) {
5109 bool show_properties
, show_status
, show_help
, new_line
= false;
5110 bool ellipsized
= false;
5116 show_properties
= streq(argv
[0], "show");
5117 show_status
= streq(argv
[0], "status");
5118 show_help
= streq(argv
[0], "help");
5120 if (show_help
&& argc
<= 1) {
5121 log_error("This command expects one or more unit names. Did you mean --help?");
5125 r
= acquire_bus(BUS_MANAGER
, &bus
);
5129 pager_open(arg_no_pager
, false);
5132 /* Increase max number of open files to 16K if we can, we
5133 * might needs this when browsing journal files, which might
5134 * be split up into many files. */
5135 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
5137 /* If no argument is specified inspect the manager itself */
5138 if (show_properties
&& argc
<= 1)
5139 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", NULL
, show_properties
, &new_line
, &ellipsized
);
5141 if (show_status
&& argc
<= 1) {
5143 show_system_status(bus
);
5147 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
5149 _cleanup_free_
char **patterns
= NULL
;
5152 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
5153 _cleanup_free_
char *path
= NULL
, *unit
= NULL
;
5156 if (safe_atou32(*name
, &id
) < 0) {
5157 if (strv_push(&patterns
, *name
) < 0)
5161 } else if (show_properties
) {
5162 /* Interpret as job id */
5163 if (asprintf(&path
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
5167 /* Interpret as PID */
5168 r
= get_unit_dbus_path_by_pid(bus
, id
, &path
);
5174 r
= unit_name_from_dbus_path(path
, &unit
);
5179 r
= show_one(argv
[0], bus
, path
, unit
, show_properties
, &new_line
, &ellipsized
);
5182 else if (r
> 0 && ret
== 0)
5186 if (!strv_isempty(patterns
)) {
5187 _cleanup_strv_free_
char **names
= NULL
;
5189 r
= expand_names(bus
, patterns
, NULL
, &names
);
5191 return log_error_errno(r
, "Failed to expand names: %m");
5193 STRV_FOREACH(name
, names
) {
5194 _cleanup_free_
char *path
;
5196 path
= unit_dbus_path_from_name(*name
);
5200 r
= show_one(argv
[0], bus
, path
, *name
, show_properties
, &new_line
, &ellipsized
);
5203 if (r
> 0 && ret
== 0)
5209 if (ellipsized
&& !arg_quiet
)
5210 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5215 static int cat_file(const char *filename
, bool newline
) {
5216 _cleanup_close_
int fd
;
5218 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
5222 printf("%s%s# %s%s\n",
5223 newline
? "\n" : "",
5224 ansi_highlight_blue(),
5229 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
5232 static int cat(int argc
, char *argv
[], void *userdata
) {
5233 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5234 _cleanup_strv_free_
char **names
= NULL
;
5240 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5241 log_error("Cannot remotely cat units.");
5245 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
5247 return log_error_errno(r
, "Failed to determine unit paths: %m");
5249 r
= acquire_bus(BUS_MANAGER
, &bus
);
5253 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5255 return log_error_errno(r
, "Failed to expand names: %m");
5257 pager_open(arg_no_pager
, false);
5259 STRV_FOREACH(name
, names
) {
5260 _cleanup_free_
char *fragment_path
= NULL
;
5261 _cleanup_strv_free_
char **dropin_paths
= NULL
;
5264 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
5275 if (need_daemon_reload(bus
, *name
))
5277 "%s# Warning: %s changed on disk, the version systemd has loaded is outdated.\n"
5278 "%s# This output shows the current version of the unit's original fragment and drop-in files.\n"
5279 "%s# If fragments or drop-ins were added or removed, they are not properly reflected in this output.\n"
5280 "%s# Run 'systemctl%s daemon-reload' to reload units.%s\n",
5281 ansi_highlight_red(),
5283 ansi_highlight_red(),
5284 ansi_highlight_red(),
5285 ansi_highlight_red(),
5286 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
5289 if (fragment_path
) {
5290 r
= cat_file(fragment_path
, false);
5292 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
5295 STRV_FOREACH(path
, dropin_paths
) {
5296 r
= cat_file(*path
, path
== dropin_paths
);
5298 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
5305 static int set_property(int argc
, char *argv
[], void *userdata
) {
5306 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5307 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5308 _cleanup_free_
char *n
= NULL
;
5312 r
= acquire_bus(BUS_MANAGER
, &bus
);
5316 polkit_agent_open_if_enabled();
5318 r
= sd_bus_message_new_method_call(
5321 "org.freedesktop.systemd1",
5322 "/org/freedesktop/systemd1",
5323 "org.freedesktop.systemd1.Manager",
5324 "SetUnitProperties");
5326 return bus_log_create_error(r
);
5328 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
5330 return log_error_errno(r
, "Failed to mangle unit name: %m");
5332 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
5334 return bus_log_create_error(r
);
5336 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
5338 return bus_log_create_error(r
);
5340 r
= bus_append_unit_property_assignment_many(m
, strv_skip(argv
, 2));
5344 r
= sd_bus_message_close_container(m
);
5346 return bus_log_create_error(r
);
5348 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5350 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
5355 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5356 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5357 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5362 r
= acquire_bus(BUS_MANAGER
, &bus
);
5366 polkit_agent_open_if_enabled();
5368 switch (arg_action
) {
5375 method
= "Reexecute";
5378 case ACTION_SYSTEMCTL
:
5379 method
= streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5380 /* "daemon-reload" */ "Reload";
5384 assert_not_reached("Unexpected action");
5387 r
= sd_bus_message_new_method_call(
5390 "org.freedesktop.systemd1",
5391 "/org/freedesktop/systemd1",
5392 "org.freedesktop.systemd1.Manager",
5395 return bus_log_create_error(r
);
5397 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5398 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5399 * their timeout, and for everything else there's the same time budget in place. */
5401 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
5403 /* On reexecution, we expect a disconnect, not a reply */
5404 if (IN_SET(r
, -ETIMEDOUT
, -ECONNRESET
) && streq(method
, "Reexecute"))
5407 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5408 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5410 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5411 * old ways of doing things, hence don't log any error in that case here. */
5413 return r
< 0 ? r
: 0;
5416 static int trivial_method(int argc
, char *argv
[], void *userdata
) {
5417 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5422 r
= acquire_bus(BUS_MANAGER
, &bus
);
5426 polkit_agent_open_if_enabled();
5429 streq(argv
[0], "clear-jobs") ||
5430 streq(argv
[0], "cancel") ? "ClearJobs" :
5431 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5432 streq(argv
[0], "halt") ? "Halt" :
5433 streq(argv
[0], "reboot") ? "Reboot" :
5434 streq(argv
[0], "kexec") ? "KExec" :
5435 streq(argv
[0], "exit") ? "Exit" :
5436 /* poweroff */ "PowerOff";
5438 r
= sd_bus_call_method(
5440 "org.freedesktop.systemd1",
5441 "/org/freedesktop/systemd1",
5442 "org.freedesktop.systemd1.Manager",
5447 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5448 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5450 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5451 * old ways of doing things, hence don't log any error in that case here. */
5453 return r
< 0 ? r
: 0;
5456 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5457 _cleanup_strv_free_
char **names
= NULL
;
5463 return trivial_method(argc
, argv
, userdata
);
5465 r
= acquire_bus(BUS_MANAGER
, &bus
);
5469 polkit_agent_open_if_enabled();
5471 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5473 return log_error_errno(r
, "Failed to expand names: %m");
5475 STRV_FOREACH(name
, names
) {
5476 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5478 q
= sd_bus_call_method(
5480 "org.freedesktop.systemd1",
5481 "/org/freedesktop/systemd1",
5482 "org.freedesktop.systemd1.Manager",
5488 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5497 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5498 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5499 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5504 r
= acquire_bus(BUS_MANAGER
, &bus
);
5508 pager_open(arg_no_pager
, false);
5510 r
= sd_bus_get_property(
5512 "org.freedesktop.systemd1",
5513 "/org/freedesktop/systemd1",
5514 "org.freedesktop.systemd1.Manager",
5520 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5522 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5524 return bus_log_parse_error(r
);
5526 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5529 return bus_log_parse_error(r
);
5531 r
= sd_bus_message_exit_container(reply
);
5533 return bus_log_parse_error(r
);
5538 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5539 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5540 _cleanup_free_
char *cmdline_init
= NULL
;
5541 const char *root
, *init
;
5545 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5546 log_error("Cannot switch root remotely.");
5550 if (argc
< 2 || argc
> 3) {
5551 log_error("Wrong number of arguments.");
5560 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5561 "init", &cmdline_init
,
5564 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5566 init
= cmdline_init
;
5569 init
= empty_to_null(init
);
5571 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5573 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5574 root_init_path
= strjoina(root
, "/", init
);
5576 /* If the passed init is actually the same as the
5577 * systemd binary, then let's suppress it. */
5578 if (files_same(root_init_path
, root_systemd_path
) > 0)
5582 r
= acquire_bus(BUS_MANAGER
, &bus
);
5586 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5588 r
= sd_bus_call_method(
5590 "org.freedesktop.systemd1",
5591 "/org/freedesktop/systemd1",
5592 "org.freedesktop.systemd1.Manager",
5598 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5603 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5604 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5605 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5613 r
= acquire_bus(BUS_MANAGER
, &bus
);
5617 polkit_agent_open_if_enabled();
5619 method
= streq(argv
[0], "set-environment")
5621 : "UnsetEnvironment";
5623 r
= sd_bus_message_new_method_call(
5626 "org.freedesktop.systemd1",
5627 "/org/freedesktop/systemd1",
5628 "org.freedesktop.systemd1.Manager",
5631 return bus_log_create_error(r
);
5633 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5635 return bus_log_create_error(r
);
5637 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5639 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5644 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5645 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5646 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5650 r
= acquire_bus(BUS_MANAGER
, &bus
);
5654 polkit_agent_open_if_enabled();
5656 r
= sd_bus_message_new_method_call(
5659 "org.freedesktop.systemd1",
5660 "/org/freedesktop/systemd1",
5661 "org.freedesktop.systemd1.Manager",
5664 return bus_log_create_error(r
);
5667 r
= sd_bus_message_append_strv(m
, environ
);
5671 r
= sd_bus_message_open_container(m
, 'a', "s");
5673 return bus_log_create_error(r
);
5675 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5677 if (!env_name_is_valid(*a
)) {
5678 log_error("Not a valid environment variable name: %s", *a
);
5682 STRV_FOREACH(b
, environ
) {
5685 eq
= startswith(*b
, *a
);
5686 if (eq
&& *eq
== '=') {
5688 r
= sd_bus_message_append(m
, "s", *b
);
5690 return bus_log_create_error(r
);
5697 r
= sd_bus_message_close_container(m
);
5700 return bus_log_create_error(r
);
5702 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5704 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5709 static int enable_sysv_units(const char *verb
, char **args
) {
5712 #if defined(HAVE_SYSV_COMPAT)
5713 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5716 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5718 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5721 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5724 if (!STR_IN_SET(verb
,
5730 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5737 const char *argv
[] = {
5738 ROOTLIBEXECDIR
"/systemd-sysv-install",
5745 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5746 bool found_native
= false, found_sysv
;
5755 if (!endswith(name
, ".service"))
5758 if (path_is_absolute(name
))
5761 j
= unit_file_exists(arg_scope
, &paths
, name
);
5762 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5763 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5764 found_native
= j
!= 0;
5766 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5767 * prefer the native unit */
5768 if (found_native
&& streq(verb
, "is-enabled"))
5771 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5775 p
[strlen(p
) - strlen(".service")] = 0;
5776 found_sysv
= access(p
, F_OK
) >= 0;
5782 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5784 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5787 if (!isempty(arg_root
))
5788 argv
[c
++] = q
= strappend("--root=", arg_root
);
5791 argv
[c
++] = basename(p
);
5794 l
= strv_join((char**)argv
, " ");
5798 log_info("Executing: %s", l
);
5802 return log_error_errno(errno
, "Failed to fork: %m");
5803 else if (pid
== 0) {
5806 (void) reset_all_signal_handlers();
5807 (void) reset_signal_mask();
5809 execv(argv
[0], (char**) argv
);
5810 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
5811 _exit(EXIT_FAILURE
);
5814 j
= wait_for_terminate(pid
, &status
);
5816 return log_error_errno(j
, "Failed to wait for child: %m");
5818 if (status
.si_code
== CLD_EXITED
) {
5819 if (streq(verb
, "is-enabled")) {
5820 if (status
.si_status
== 0) {
5829 } else if (status
.si_status
!= 0)
5830 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
5832 log_error("Unexpected waitid() result.");
5839 /* Remove this entry, so that we don't try enabling it as native unit */
5842 assert(args
[f
] == name
);
5843 strv_remove(args
, name
);
5850 static int mangle_names(char **original_names
, char ***mangled_names
) {
5851 char **i
, **l
, **name
;
5854 l
= i
= new(char*, strv_length(original_names
) + 1);
5858 STRV_FOREACH(name
, original_names
) {
5860 /* When enabling units qualified path names are OK,
5861 * too, hence allow them explicitly. */
5863 if (is_path(*name
)) {
5870 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5873 return log_error_errno(r
, "Failed to mangle unit name: %m");
5886 static int normalize_names(char **names
, bool warn_if_path
) {
5888 bool was_path
= false;
5890 STRV_FOREACH(u
, names
) {
5896 r
= free_and_strdup(u
, basename(*u
));
5898 return log_error_errno(r
, "Failed to normalize unit file path: %m");
5903 if (warn_if_path
&& was_path
)
5904 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
5909 static int unit_exists(const char *unit
) {
5910 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5911 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5912 _cleanup_free_
char *path
= NULL
;
5913 static const struct bus_properties_map property_map
[] = {
5914 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
5915 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
)},
5918 UnitStatusInfo info
= {};
5922 path
= unit_dbus_path_from_name(unit
);
5926 r
= acquire_bus(BUS_MANAGER
, &bus
);
5930 r
= sd_bus_call_method(
5932 "org.freedesktop.systemd1",
5934 "org.freedesktop.DBus.Properties",
5940 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
5942 r
= bus_message_map_all_properties(reply
, property_map
, &info
);
5944 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
5946 return !streq_ptr(info
.load_state
, "not-found") || !streq_ptr(info
.active_state
, "inactive");
5949 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5950 _cleanup_strv_free_
char **names
= NULL
;
5951 const char *verb
= argv
[0];
5952 UnitFileChange
*changes
= NULL
;
5953 unsigned n_changes
= 0;
5954 int carries_install_info
= -1;
5955 bool ignore_carries_install_info
= arg_quiet
;
5961 r
= mangle_names(strv_skip(argv
, 1), &names
);
5965 r
= enable_sysv_units(verb
, names
);
5969 /* If the operation was fully executed by the SysV compat, let's finish early */
5970 if (strv_isempty(names
)) {
5971 if (arg_no_reload
|| install_client_side())
5973 return daemon_reload(argc
, argv
, userdata
);
5976 if (streq(verb
, "disable")) {
5977 r
= normalize_names(names
, true);
5982 if (install_client_side()) {
5983 UnitFileFlags flags
;
5985 flags
= args_to_flags();
5986 if (streq(verb
, "enable")) {
5987 r
= unit_file_enable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
5988 carries_install_info
= r
;
5989 } else if (streq(verb
, "disable"))
5990 r
= unit_file_disable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
5991 else if (streq(verb
, "reenable")) {
5992 r
= unit_file_reenable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
5993 carries_install_info
= r
;
5994 } else if (streq(verb
, "link"))
5995 r
= unit_file_link(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
5996 else if (streq(verb
, "preset")) {
5997 r
= unit_file_preset(arg_scope
, flags
, arg_root
, names
, arg_preset_mode
, &changes
, &n_changes
);
5998 } else if (streq(verb
, "mask"))
5999 r
= unit_file_mask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6000 else if (streq(verb
, "unmask"))
6001 r
= unit_file_unmask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6002 else if (streq(verb
, "revert"))
6003 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
6005 assert_not_reached("Unknown verb");
6007 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
6012 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6013 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6014 bool expect_carries_install_info
= false;
6015 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
6019 if (STR_IN_SET(verb
, "mask", "unmask")) {
6020 r
= unit_exists(*names
);
6024 log_notice("Unit %s does not exist, proceeding anyway.", *names
);
6027 r
= acquire_bus(BUS_MANAGER
, &bus
);
6031 polkit_agent_open_if_enabled();
6033 if (streq(verb
, "enable")) {
6034 method
= "EnableUnitFiles";
6035 expect_carries_install_info
= true;
6036 } else if (streq(verb
, "disable")) {
6037 method
= "DisableUnitFiles";
6039 } else if (streq(verb
, "reenable")) {
6040 method
= "ReenableUnitFiles";
6041 expect_carries_install_info
= true;
6042 } else if (streq(verb
, "link"))
6043 method
= "LinkUnitFiles";
6044 else if (streq(verb
, "preset")) {
6046 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
6047 method
= "PresetUnitFilesWithMode";
6048 send_preset_mode
= true;
6050 method
= "PresetUnitFiles";
6052 expect_carries_install_info
= true;
6053 ignore_carries_install_info
= true;
6054 } else if (streq(verb
, "mask"))
6055 method
= "MaskUnitFiles";
6056 else if (streq(verb
, "unmask")) {
6057 method
= "UnmaskUnitFiles";
6059 } else if (streq(verb
, "revert")) {
6060 method
= "RevertUnitFiles";
6061 send_runtime
= send_force
= false;
6063 assert_not_reached("Unknown verb");
6065 r
= sd_bus_message_new_method_call(
6068 "org.freedesktop.systemd1",
6069 "/org/freedesktop/systemd1",
6070 "org.freedesktop.systemd1.Manager",
6073 return bus_log_create_error(r
);
6075 r
= sd_bus_message_append_strv(m
, names
);
6077 return bus_log_create_error(r
);
6079 if (send_preset_mode
) {
6080 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
6082 return bus_log_create_error(r
);
6086 r
= sd_bus_message_append(m
, "b", arg_runtime
);
6088 return bus_log_create_error(r
);
6092 r
= sd_bus_message_append(m
, "b", arg_force
);
6094 return bus_log_create_error(r
);
6097 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6099 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
6101 if (expect_carries_install_info
) {
6102 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
6104 return bus_log_parse_error(r
);
6107 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6111 /* Try to reload if enabled */
6113 r
= daemon_reload(argc
, argv
, userdata
);
6118 if (carries_install_info
== 0 && !ignore_carries_install_info
)
6119 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6120 "settings in the [Install] section, and DefaultInstance for template units).\n"
6121 "This means they are not meant to be enabled using systemctl.\n"
6122 "Possible reasons for having this kind of units are:\n"
6123 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6124 " .wants/ or .requires/ directory.\n"
6125 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6126 " a requirement dependency on it.\n"
6127 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6128 " D-Bus, udev, scripted systemctl call, ...).\n"
6129 "4) In case of template units, the unit is meant to be enabled with some\n"
6130 " instance name specified.");
6132 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
6133 char *new_args
[n_changes
+ 2];
6137 r
= acquire_bus(BUS_MANAGER
, &bus
);
6141 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
6142 for (i
= 0; i
< n_changes
; i
++)
6143 new_args
[i
+ 1] = basename(changes
[i
].path
);
6144 new_args
[i
+ 1] = NULL
;
6146 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
6150 unit_file_changes_free(changes
, n_changes
);
6155 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
6156 _cleanup_strv_free_
char **names
= NULL
;
6157 _cleanup_free_
char *target
= NULL
;
6158 const char *verb
= argv
[0];
6159 UnitFileChange
*changes
= NULL
;
6160 unsigned n_changes
= 0;
6167 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
6169 return log_error_errno(r
, "Failed to mangle unit name: %m");
6171 r
= mangle_names(strv_skip(argv
, 2), &names
);
6175 if (streq(verb
, "add-wants"))
6177 else if (streq(verb
, "add-requires"))
6178 dep
= UNIT_REQUIRES
;
6180 assert_not_reached("Unknown verb");
6182 if (install_client_side()) {
6183 r
= unit_file_add_dependency(arg_scope
, args_to_flags(), arg_root
, names
, target
, dep
, &changes
, &n_changes
);
6184 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
6189 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6190 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6193 r
= acquire_bus(BUS_MANAGER
, &bus
);
6197 polkit_agent_open_if_enabled();
6199 r
= sd_bus_message_new_method_call(
6202 "org.freedesktop.systemd1",
6203 "/org/freedesktop/systemd1",
6204 "org.freedesktop.systemd1.Manager",
6205 "AddDependencyUnitFiles");
6207 return bus_log_create_error(r
);
6209 r
= sd_bus_message_append_strv(m
, names
);
6211 return bus_log_create_error(r
);
6213 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
6215 return bus_log_create_error(r
);
6217 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6219 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
6221 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6225 if (arg_no_reload
) {
6230 r
= daemon_reload(argc
, argv
, userdata
);
6234 unit_file_changes_free(changes
, n_changes
);
6239 static int preset_all(int argc
, char *argv
[], void *userdata
) {
6240 UnitFileChange
*changes
= NULL
;
6241 unsigned n_changes
= 0;
6244 if (install_client_side()) {
6245 r
= unit_file_preset_all(arg_scope
, args_to_flags(), arg_root
, arg_preset_mode
, &changes
, &n_changes
);
6246 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
6251 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6252 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6255 r
= acquire_bus(BUS_MANAGER
, &bus
);
6259 polkit_agent_open_if_enabled();
6261 r
= sd_bus_call_method(
6263 "org.freedesktop.systemd1",
6264 "/org/freedesktop/systemd1",
6265 "org.freedesktop.systemd1.Manager",
6266 "PresetAllUnitFiles",
6270 unit_file_preset_mode_to_string(arg_preset_mode
),
6274 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
6276 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6280 if (arg_no_reload
) {
6285 r
= daemon_reload(argc
, argv
, userdata
);
6289 unit_file_changes_free(changes
, n_changes
);
6294 static int show_installation_targets_client_side(const char *name
) {
6295 UnitFileChange
*changes
= NULL
;
6296 unsigned n_changes
= 0, i
;
6297 UnitFileFlags flags
;
6301 p
= STRV_MAKE(name
);
6302 flags
= UNIT_FILE_DRY_RUN
|
6303 (arg_runtime
? UNIT_FILE_RUNTIME
: 0);
6305 r
= unit_file_disable(UNIT_FILE_SYSTEM
, flags
, NULL
, p
, &changes
, &n_changes
);
6307 return log_error_errno(r
, "Failed to get file links for %s: %m", name
);
6309 for (i
= 0; i
< n_changes
; i
++)
6310 if (changes
[i
].type
== UNIT_FILE_UNLINK
)
6311 printf(" %s\n", changes
[i
].path
);
6316 static int show_installation_targets(sd_bus
*bus
, const char *name
) {
6317 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6318 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6322 r
= sd_bus_call_method(
6324 "org.freedesktop.systemd1",
6325 "/org/freedesktop/systemd1",
6326 "org.freedesktop.systemd1.Manager",
6330 "sb", name
, arg_runtime
);
6332 return log_error_errno(r
, "Failed to get unit file links for %s: %s", name
, bus_error_message(&error
, r
));
6334 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
6336 return bus_log_parse_error(r
);
6338 while ((r
= sd_bus_message_read(reply
, "s", &link
)) > 0)
6339 printf(" %s\n", link
);
6342 return bus_log_parse_error(r
);
6344 r
= sd_bus_message_exit_container(reply
);
6346 return bus_log_parse_error(r
);
6351 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
6353 _cleanup_strv_free_
char **names
= NULL
;
6358 r
= mangle_names(strv_skip(argv
, 1), &names
);
6362 r
= enable_sysv_units(argv
[0], names
);
6368 if (install_client_side()) {
6369 STRV_FOREACH(name
, names
) {
6370 UnitFileState state
;
6372 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
6374 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
6378 UNIT_FILE_ENABLED_RUNTIME
,
6381 UNIT_FILE_GENERATED
))
6385 puts(unit_file_state_to_string(state
));
6387 r
= show_installation_targets_client_side(*name
);
6396 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6399 r
= acquire_bus(BUS_MANAGER
, &bus
);
6403 STRV_FOREACH(name
, names
) {
6404 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6407 r
= sd_bus_call_method(
6409 "org.freedesktop.systemd1",
6410 "/org/freedesktop/systemd1",
6411 "org.freedesktop.systemd1.Manager",
6417 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
6419 r
= sd_bus_message_read(reply
, "s", &s
);
6421 return bus_log_parse_error(r
);
6423 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6429 r
= show_installation_targets(bus
, *name
);
6437 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
6440 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
6441 _cleanup_free_
char *state
= NULL
;
6445 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
6448 return EXIT_FAILURE
;
6451 r
= acquire_bus(BUS_MANAGER
, &bus
);
6455 r
= sd_bus_get_property_string(
6457 "org.freedesktop.systemd1",
6458 "/org/freedesktop/systemd1",
6459 "org.freedesktop.systemd1.Manager",
6472 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
6475 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
6476 _cleanup_free_
char *t
= NULL
;
6480 assert(original_path
);
6483 r
= tempfn_random(new_path
, NULL
, &t
);
6485 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
6487 r
= mkdir_parents(new_path
, 0755);
6489 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
6491 r
= copy_file(original_path
, t
, 0, 0644, 0);
6496 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
6499 return log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", new_path
);
6507 static int get_file_to_edit(
6508 const LookupPaths
*paths
,
6512 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
6517 path
= strjoin(paths
->persistent_config
, "/", name
, NULL
);
6522 run
= strjoin(paths
->runtime_config
, "/", name
, NULL
);
6528 if (access(path
, F_OK
) >= 0) {
6529 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
6543 static int unit_file_create_new(
6544 const LookupPaths
*paths
,
6545 const char *unit_name
,
6547 char **ret_new_path
,
6548 char **ret_tmp_path
) {
6550 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6554 assert(ret_new_path
);
6555 assert(ret_tmp_path
);
6557 ending
= strjoina(unit_name
, suffix
);
6558 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
6562 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6568 *ret_new_path
= tmp_new_path
;
6569 *ret_tmp_path
= tmp_tmp_path
;
6574 static int unit_file_create_copy(
6575 const LookupPaths
*paths
,
6576 const char *unit_name
,
6577 const char *fragment_path
,
6578 char **ret_new_path
,
6579 char **ret_tmp_path
) {
6581 char *tmp_new_path
, *tmp_tmp_path
;
6584 assert(fragment_path
);
6586 assert(ret_new_path
);
6587 assert(ret_tmp_path
);
6589 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6593 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6596 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6601 if (response
!= 'y') {
6602 log_warning("%s ignored", unit_name
);
6604 return -EKEYREJECTED
;
6608 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6614 *ret_new_path
= tmp_new_path
;
6615 *ret_tmp_path
= tmp_tmp_path
;
6620 static int run_editor(char **paths
) {
6628 return log_error_errno(errno
, "Failed to fork: %m");
6632 char *editor
, **editor_args
= NULL
;
6633 char **tmp_path
, **original_path
, *p
;
6634 unsigned n_editor_args
= 0, i
= 1;
6637 (void) reset_all_signal_handlers();
6638 (void) reset_signal_mask();
6640 argc
= strv_length(paths
)/2 + 1;
6642 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6643 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6644 * we try to execute well known editors
6646 editor
= getenv("SYSTEMD_EDITOR");
6648 editor
= getenv("EDITOR");
6650 editor
= getenv("VISUAL");
6652 if (!isempty(editor
)) {
6653 editor_args
= strv_split(editor
, WHITESPACE
);
6656 _exit(EXIT_FAILURE
);
6658 n_editor_args
= strv_length(editor_args
);
6659 argc
+= n_editor_args
- 1;
6661 args
= newa(const char*, argc
+ 1);
6663 if (n_editor_args
> 0) {
6664 args
[0] = editor_args
[0];
6665 for (; i
< n_editor_args
; i
++)
6666 args
[i
] = editor_args
[i
];
6669 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6670 args
[i
] = *tmp_path
;
6675 if (n_editor_args
> 0)
6676 execvp(args
[0], (char* const*) args
);
6678 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6680 execvp(p
, (char* const*) args
);
6681 /* We do not fail if the editor doesn't exist
6682 * because we want to try each one of them before
6685 if (errno
!= ENOENT
) {
6686 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6687 _exit(EXIT_FAILURE
);
6691 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6692 _exit(EXIT_FAILURE
);
6695 r
= wait_for_terminate_and_warn("editor", pid
, true);
6697 return log_error_errno(r
, "Failed to wait for child: %m");
6702 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6703 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6710 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6714 STRV_FOREACH(name
, names
) {
6715 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
;
6717 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6720 else if (!arg_force
) {
6722 log_error("Run 'systemctl edit --force %s' to create a new unit.", *name
);
6725 // FIXME: support units with path==NULL (no FragmentPath)
6726 log_error("No fragment exists for %s.", *name
);
6733 r
= unit_file_create_copy(&lp
, *name
, path
, &new_path
, &tmp_path
);
6735 r
= unit_file_create_new(&lp
, *name
, ".d/override.conf", &new_path
, &tmp_path
);
6737 r
= unit_file_create_new(&lp
, *name
, NULL
, &new_path
, &tmp_path
);
6741 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6744 new_path
= tmp_path
= NULL
;
6750 static int edit(int argc
, char *argv
[], void *userdata
) {
6751 _cleanup_strv_free_
char **names
= NULL
;
6752 _cleanup_strv_free_
char **paths
= NULL
;
6753 char **original
, **tmp
;
6758 log_error("Cannot edit units if not on a tty.");
6762 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6763 log_error("Cannot edit units remotely.");
6767 r
= acquire_bus(BUS_MANAGER
, &bus
);
6771 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6773 return log_error_errno(r
, "Failed to expand names: %m");
6775 r
= find_paths_to_edit(bus
, names
, &paths
);
6779 if (strv_isempty(paths
))
6782 r
= run_editor(paths
);
6786 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6787 /* If the temporary file is empty we ignore it. It's
6788 * useful if the user wants to cancel its modification
6790 if (null_or_empty_path(*tmp
)) {
6791 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6795 r
= rename(*tmp
, *original
);
6797 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6804 if (!arg_no_reload
&& !install_client_side())
6805 r
= daemon_reload(argc
, argv
, userdata
);
6808 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6809 (void) unlink(*tmp
);
6811 /* Removing empty dropin dirs */
6813 _cleanup_free_
char *dir
;
6815 dir
= dirname_malloc(*original
);
6819 /* no need to check if the dir is empty, rmdir
6820 * does nothing if it is not the case.
6829 static void systemctl_help(void) {
6831 pager_open(arg_no_pager
, false);
6833 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6834 "Query or send control commands to the systemd manager.\n\n"
6835 " -h --help Show this help\n"
6836 " --version Show package version\n"
6837 " --system Connect to system manager\n"
6838 " --user Connect to user service manager\n"
6839 " -H --host=[USER@]HOST\n"
6840 " Operate on remote host\n"
6841 " -M --machine=CONTAINER\n"
6842 " Operate on local container\n"
6843 " -t --type=TYPE List units of a particular type\n"
6844 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6845 " -p --property=NAME Show only properties by this name\n"
6846 " -a --all Show all properties/all units currently in memory,\n"
6847 " including dead/empty ones. To list all units installed on\n"
6848 " the system, use the 'list-unit-files' command instead.\n"
6849 " -l --full Don't ellipsize unit names on output\n"
6850 " -r --recursive Show unit list of host and local containers\n"
6851 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6852 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6853 " queueing a new job\n"
6854 " --show-types When showing sockets, explicitly show their type\n"
6855 " --value When showing properties, only print the value\n"
6856 " -i --ignore-inhibitors\n"
6857 " When shutting down or sleeping, ignore inhibitors\n"
6858 " --kill-who=WHO Who to send signal to\n"
6859 " -s --signal=SIGNAL Which signal to send\n"
6860 " --now Start or stop unit in addition to enabling or disabling it\n"
6861 " -q --quiet Suppress output\n"
6862 " --wait For (re)start, wait until service stopped again\n"
6863 " --no-block Do not wait until operation finished\n"
6864 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6865 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6866 " --no-legend Do not print a legend (column headers and hints)\n"
6867 " --no-pager Do not pipe output into a pager\n"
6868 " --no-ask-password\n"
6869 " Do not ask for system passwords\n"
6870 " --global Enable/disable unit files globally\n"
6871 " --runtime Enable unit files only temporarily until next reboot\n"
6872 " -f --force When enabling unit files, override existing symlinks\n"
6873 " When shutting down, execute action immediately\n"
6874 " --preset-mode= Apply only enable, only disable, or all presets\n"
6875 " --root=PATH Enable unit files in the specified root directory\n"
6876 " -n --lines=INTEGER Number of journal entries to show\n"
6877 " -o --output=STRING Change journal output mode (short, short-precise,\n"
6878 " short-iso, short-full, short-monotonic, short-unix,\n"
6879 " verbose, export, json, json-pretty, json-sse, cat)\n"
6880 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6881 " --plain Print unit dependencies as a list instead of a tree\n\n"
6883 " list-units [PATTERN...] List units currently in memory\n"
6884 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
6886 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
6888 " start NAME... Start (activate) one or more units\n"
6889 " stop NAME... Stop (deactivate) one or more units\n"
6890 " reload NAME... Reload one or more units\n"
6891 " restart NAME... Start or restart one or more units\n"
6892 " try-restart NAME... Restart one or more units if active\n"
6893 " reload-or-restart NAME... Reload one or more units if possible,\n"
6894 " otherwise start or restart\n"
6895 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6896 " if supported, otherwise restart\n"
6897 " isolate NAME Start one unit and stop all others\n"
6898 " kill NAME... Send signal to processes of a unit\n"
6899 " is-active PATTERN... Check whether units are active\n"
6900 " is-failed PATTERN... Check whether units are failed\n"
6901 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6902 " show [PATTERN...|JOB...] Show properties of one or more\n"
6903 " units/jobs or the manager\n"
6904 " cat PATTERN... Show files and drop-ins of one or more units\n"
6905 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6906 " help PATTERN...|PID... Show manual for one or more units\n"
6907 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6909 " list-dependencies [NAME] Recursively show units which are required\n"
6910 " or wanted by this unit or by which this\n"
6911 " unit is required or wanted\n\n"
6912 "Unit File Commands:\n"
6913 " list-unit-files [PATTERN...] List installed unit files\n"
6914 " enable [NAME...|PATH...] Enable one or more unit files\n"
6915 " disable NAME... Disable one or more unit files\n"
6916 " reenable NAME... Reenable one or more unit files\n"
6917 " preset NAME... Enable/disable one or more unit files\n"
6918 " based on preset configuration\n"
6919 " preset-all Enable/disable all unit files based on\n"
6920 " preset configuration\n"
6921 " is-enabled NAME... Check whether unit files are enabled\n"
6922 " mask NAME... Mask one or more units\n"
6923 " unmask NAME... Unmask one or more units\n"
6924 " link PATH... Link one or more units files into\n"
6925 " the search path\n"
6926 " revert NAME... Revert one or more unit files to vendor\n"
6928 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6929 " on specified one or more units\n"
6930 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6931 " on specified one or more units\n"
6932 " edit NAME... Edit one or more unit files\n"
6933 " get-default Get the name of the default target\n"
6934 " set-default NAME Set the default target\n\n"
6935 "Machine Commands:\n"
6936 " list-machines [PATTERN...] List local containers and host\n\n"
6938 " list-jobs [PATTERN...] List jobs\n"
6939 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6940 "Environment Commands:\n"
6941 " show-environment Dump environment\n"
6942 " set-environment NAME=VALUE... Set one or more environment variables\n"
6943 " unset-environment NAME... Unset one or more environment variables\n"
6944 " import-environment [NAME...] Import all or some environment variables\n\n"
6945 "Manager Lifecycle Commands:\n"
6946 " daemon-reload Reload systemd manager configuration\n"
6947 " daemon-reexec Reexecute systemd manager\n\n"
6948 "System Commands:\n"
6949 " is-system-running Check whether system is fully running\n"
6950 " default Enter system default mode\n"
6951 " rescue Enter system rescue mode\n"
6952 " emergency Enter system emergency mode\n"
6953 " halt Shut down and halt the system\n"
6954 " poweroff Shut down and power-off the system\n"
6955 " reboot [ARG] Shut down and reboot the system\n"
6956 " kexec Shut down and reboot the system with kexec\n"
6957 " exit [EXIT_CODE] Request user instance or container exit\n"
6958 " switch-root ROOT [INIT] Change to a different root file system\n"
6959 " suspend Suspend the system\n"
6960 " hibernate Hibernate the system\n"
6961 " hybrid-sleep Hibernate and suspend the system\n",
6962 program_invocation_short_name
);
6965 static void halt_help(void) {
6966 printf("%s [OPTIONS...]%s\n\n"
6967 "%s the system.\n\n"
6968 " --help Show this help\n"
6969 " --halt Halt the machine\n"
6970 " -p --poweroff Switch off the machine\n"
6971 " --reboot Reboot the machine\n"
6972 " -f --force Force immediate halt/power-off/reboot\n"
6973 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6974 " -d --no-wtmp Don't write wtmp record\n"
6975 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6976 program_invocation_short_name
,
6977 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6978 arg_action
== ACTION_REBOOT
? "Reboot" :
6979 arg_action
== ACTION_POWEROFF
? "Power off" :
6983 static void shutdown_help(void) {
6984 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6985 "Shut down the system.\n\n"
6986 " --help Show this help\n"
6987 " -H --halt Halt the machine\n"
6988 " -P --poweroff Power-off the machine\n"
6989 " -r --reboot Reboot the machine\n"
6990 " -h Equivalent to --poweroff, overridden by --halt\n"
6991 " -k Don't halt/power-off/reboot, just send warnings\n"
6992 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6993 " -c Cancel a pending shutdown\n",
6994 program_invocation_short_name
);
6997 static void telinit_help(void) {
6998 printf("%s [OPTIONS...] {COMMAND}\n\n"
6999 "Send control commands to the init daemon.\n\n"
7000 " --help Show this help\n"
7001 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7003 " 0 Power-off the machine\n"
7004 " 6 Reboot the machine\n"
7005 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7006 " 1, s, S Enter rescue mode\n"
7007 " q, Q Reload init daemon configuration\n"
7008 " u, U Reexecute init daemon\n",
7009 program_invocation_short_name
);
7012 static void runlevel_help(void) {
7013 printf("%s [OPTIONS...]\n\n"
7014 "Prints the previous and current runlevel of the init system.\n\n"
7015 " --help Show this help\n",
7016 program_invocation_short_name
);
7019 static void help_types(void) {
7023 puts("Available unit types:");
7024 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
7025 puts(unit_type_to_string(i
));
7028 static void help_states(void) {
7032 puts("Available unit load states:");
7033 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
7034 puts(unit_load_state_to_string(i
));
7037 puts("\nAvailable unit active states:");
7038 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
7039 puts(unit_active_state_to_string(i
));
7042 puts("\nAvailable automount unit substates:");
7043 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
7044 puts(automount_state_to_string(i
));
7047 puts("\nAvailable busname unit substates:");
7048 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
7049 puts(busname_state_to_string(i
));
7052 puts("\nAvailable device unit substates:");
7053 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
7054 puts(device_state_to_string(i
));
7057 puts("\nAvailable mount unit substates:");
7058 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
7059 puts(mount_state_to_string(i
));
7062 puts("\nAvailable path unit substates:");
7063 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
7064 puts(path_state_to_string(i
));
7067 puts("\nAvailable scope unit substates:");
7068 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
7069 puts(scope_state_to_string(i
));
7072 puts("\nAvailable service unit substates:");
7073 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
7074 puts(service_state_to_string(i
));
7077 puts("\nAvailable slice unit substates:");
7078 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
7079 puts(slice_state_to_string(i
));
7082 puts("\nAvailable socket unit substates:");
7083 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
7084 puts(socket_state_to_string(i
));
7087 puts("\nAvailable swap unit substates:");
7088 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
7089 puts(swap_state_to_string(i
));
7092 puts("\nAvailable target unit substates:");
7093 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
7094 puts(target_state_to_string(i
));
7097 puts("\nAvailable timer unit substates:");
7098 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
7099 puts(timer_state_to_string(i
));
7102 static int systemctl_parse_argv(int argc
, char *argv
[]) {
7111 ARG_IGNORE_DEPENDENCIES
,
7124 ARG_NO_ASK_PASSWORD
,
7138 static const struct option options
[] = {
7139 { "help", no_argument
, NULL
, 'h' },
7140 { "version", no_argument
, NULL
, ARG_VERSION
},
7141 { "type", required_argument
, NULL
, 't' },
7142 { "property", required_argument
, NULL
, 'p' },
7143 { "all", no_argument
, NULL
, 'a' },
7144 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
7145 { "after", no_argument
, NULL
, ARG_AFTER
},
7146 { "before", no_argument
, NULL
, ARG_BEFORE
},
7147 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
7148 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
7149 { "full", no_argument
, NULL
, 'l' },
7150 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
7151 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
7152 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
7153 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
7154 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
7155 { "value", no_argument
, NULL
, ARG_VALUE
},
7156 { "user", no_argument
, NULL
, ARG_USER
},
7157 { "system", no_argument
, NULL
, ARG_SYSTEM
},
7158 { "global", no_argument
, NULL
, ARG_GLOBAL
},
7159 { "wait", no_argument
, NULL
, ARG_WAIT
},
7160 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
7161 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
7162 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
7163 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7164 { "quiet", no_argument
, NULL
, 'q' },
7165 { "root", required_argument
, NULL
, ARG_ROOT
},
7166 { "force", no_argument
, NULL
, ARG_FORCE
},
7167 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
7168 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
7169 { "signal", required_argument
, NULL
, 's' },
7170 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
7171 { "host", required_argument
, NULL
, 'H' },
7172 { "machine", required_argument
, NULL
, 'M' },
7173 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
7174 { "lines", required_argument
, NULL
, 'n' },
7175 { "output", required_argument
, NULL
, 'o' },
7176 { "plain", no_argument
, NULL
, ARG_PLAIN
},
7177 { "state", required_argument
, NULL
, ARG_STATE
},
7178 { "recursive", no_argument
, NULL
, 'r' },
7179 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
7180 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
7181 { "now", no_argument
, NULL
, ARG_NOW
},
7182 { "message", required_argument
, NULL
, ARG_MESSAGE
},
7192 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7193 arg_ask_password
= true;
7195 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
7207 if (isempty(optarg
)) {
7208 log_error("--type requires arguments.");
7214 _cleanup_free_
char *type
= NULL
;
7216 r
= extract_first_word(&p
, &type
, ",", 0);
7218 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
7223 if (streq(type
, "help")) {
7228 if (unit_type_from_string(type
) >= 0) {
7229 if (strv_push(&arg_types
, type
) < 0)
7235 /* It's much nicer to use --state= for
7236 * load states, but let's support this
7237 * in --types= too for compatibility
7238 * with old versions */
7239 if (unit_load_state_from_string(type
) >= 0) {
7240 if (strv_push(&arg_states
, type
) < 0)
7246 log_error("Unknown unit type or load state '%s'.", type
);
7247 log_info("Use -t help to see a list of allowed values.");
7255 /* Make sure that if the empty property list
7256 was specified, we won't show any properties. */
7257 if (isempty(optarg
) && !arg_properties
) {
7258 arg_properties
= new0(char*, 1);
7259 if (!arg_properties
)
7264 _cleanup_free_
char *prop
= NULL
;
7266 r
= extract_first_word(&p
, &prop
, ",", 0);
7268 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
7273 if (strv_push(&arg_properties
, prop
) < 0)
7280 /* If the user asked for a particular
7281 * property, show it to him, even if it is
7293 arg_dependency
= DEPENDENCY_REVERSE
;
7297 arg_dependency
= DEPENDENCY_AFTER
;
7301 arg_dependency
= DEPENDENCY_BEFORE
;
7304 case ARG_SHOW_TYPES
:
7305 arg_show_types
= true;
7313 arg_job_mode
= optarg
;
7317 arg_job_mode
= "fail";
7320 case ARG_IRREVERSIBLE
:
7321 arg_job_mode
= "replace-irreversibly";
7324 case ARG_IGNORE_DEPENDENCIES
:
7325 arg_job_mode
= "ignore-dependencies";
7329 arg_scope
= UNIT_FILE_USER
;
7333 arg_scope
= UNIT_FILE_SYSTEM
;
7337 arg_scope
= UNIT_FILE_GLOBAL
;
7345 arg_no_block
= true;
7349 arg_no_legend
= true;
7353 arg_no_pager
= true;
7361 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
7371 if (strv_extend(&arg_states
, "failed") < 0)
7389 arg_no_reload
= true;
7393 arg_kill_who
= optarg
;
7397 arg_signal
= signal_from_string_try_harder(optarg
);
7398 if (arg_signal
< 0) {
7399 log_error("Failed to parse signal string %s.", optarg
);
7404 case ARG_NO_ASK_PASSWORD
:
7405 arg_ask_password
= false;
7409 arg_transport
= BUS_TRANSPORT_REMOTE
;
7414 arg_transport
= BUS_TRANSPORT_MACHINE
;
7423 if (safe_atou(optarg
, &arg_lines
) < 0) {
7424 log_error("Failed to parse lines '%s'", optarg
);
7430 arg_output
= output_mode_from_string(optarg
);
7431 if (arg_output
< 0) {
7432 log_error("Unknown output '%s'.", optarg
);
7438 arg_ignore_inhibitors
= true;
7445 case ARG_FIRMWARE_SETUP
:
7446 arg_firmware_setup
= true;
7450 if (isempty(optarg
)) {
7451 log_error("--signal requires arguments.");
7457 _cleanup_free_
char *s
= NULL
;
7459 r
= extract_first_word(&p
, &s
, ",", 0);
7461 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
7466 if (streq(s
, "help")) {
7471 if (strv_push(&arg_states
, s
) < 0)
7480 if (geteuid() != 0) {
7481 log_error("--recursive requires root privileges.");
7485 arg_recursive
= true;
7488 case ARG_PRESET_MODE
:
7490 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
7491 if (arg_preset_mode
< 0) {
7492 log_error("Failed to parse preset mode: %s.", optarg
);
7503 if (strv_extend(&arg_wall
, optarg
) < 0)
7511 assert_not_reached("Unhandled option");
7514 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
7515 log_error("Cannot access user instance remotely.");
7519 if (arg_wait
&& arg_no_block
) {
7520 log_error("--wait may not be combined with --no-block.");
7527 static int halt_parse_argv(int argc
, char *argv
[]) {
7536 static const struct option options
[] = {
7537 { "help", no_argument
, NULL
, ARG_HELP
},
7538 { "halt", no_argument
, NULL
, ARG_HALT
},
7539 { "poweroff", no_argument
, NULL
, 'p' },
7540 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
7541 { "force", no_argument
, NULL
, 'f' },
7542 { "wtmp-only", no_argument
, NULL
, 'w' },
7543 { "no-wtmp", no_argument
, NULL
, 'd' },
7544 { "no-sync", no_argument
, NULL
, 'n' },
7545 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7554 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
7555 if (runlevel
== '0' || runlevel
== '6')
7558 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
7566 arg_action
= ACTION_HALT
;
7570 if (arg_action
!= ACTION_REBOOT
)
7571 arg_action
= ACTION_POWEROFF
;
7575 arg_action
= ACTION_REBOOT
;
7600 /* Compatibility nops */
7607 assert_not_reached("Unhandled option");
7610 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7611 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7614 } else if (optind
< argc
) {
7615 log_error("Too many arguments.");
7622 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7626 if (streq(t
, "now"))
7628 else if (!strchr(t
, ':')) {
7631 if (safe_atou64(t
, &u
) < 0)
7634 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7643 hour
= strtol(t
, &e
, 10);
7644 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7647 minute
= strtol(e
+1, &e
, 10);
7648 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7651 n
= now(CLOCK_REALTIME
);
7652 s
= (time_t) (n
/ USEC_PER_SEC
);
7654 assert_se(localtime_r(&s
, &tm
));
7656 tm
.tm_hour
= (int) hour
;
7657 tm
.tm_min
= (int) minute
;
7660 assert_se(s
= mktime(&tm
));
7662 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7665 *_u
+= USEC_PER_DAY
;
7671 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7678 static const struct option options
[] = {
7679 { "help", no_argument
, NULL
, ARG_HELP
},
7680 { "halt", no_argument
, NULL
, 'H' },
7681 { "poweroff", no_argument
, NULL
, 'P' },
7682 { "reboot", no_argument
, NULL
, 'r' },
7683 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7684 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7694 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7702 arg_action
= ACTION_HALT
;
7706 arg_action
= ACTION_POWEROFF
;
7711 arg_action
= ACTION_KEXEC
;
7713 arg_action
= ACTION_REBOOT
;
7717 arg_action
= ACTION_KEXEC
;
7721 if (arg_action
!= ACTION_HALT
)
7722 arg_action
= ACTION_POWEROFF
;
7737 /* Compatibility nops */
7741 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7748 assert_not_reached("Unhandled option");
7751 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7752 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7754 log_error("Failed to parse time specification: %s", argv
[optind
]);
7758 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7760 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7761 /* No time argument for shutdown cancel */
7762 wall
= argv
+ optind
;
7763 else if (argc
> optind
+ 1)
7764 /* We skip the time argument */
7765 wall
= argv
+ optind
+ 1;
7768 arg_wall
= strv_copy(wall
);
7778 static int telinit_parse_argv(int argc
, char *argv
[]) {
7785 static const struct option options
[] = {
7786 { "help", no_argument
, NULL
, ARG_HELP
},
7787 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7791 static const struct {
7795 { '0', ACTION_POWEROFF
},
7796 { '6', ACTION_REBOOT
},
7797 { '1', ACTION_RESCUE
},
7798 { '2', ACTION_RUNLEVEL2
},
7799 { '3', ACTION_RUNLEVEL3
},
7800 { '4', ACTION_RUNLEVEL4
},
7801 { '5', ACTION_RUNLEVEL5
},
7802 { 's', ACTION_RESCUE
},
7803 { 'S', ACTION_RESCUE
},
7804 { 'q', ACTION_RELOAD
},
7805 { 'Q', ACTION_RELOAD
},
7806 { 'u', ACTION_REEXEC
},
7807 { 'U', ACTION_REEXEC
}
7816 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7831 assert_not_reached("Unhandled option");
7834 if (optind
>= argc
) {
7835 log_error("%s: required argument missing.", program_invocation_short_name
);
7839 if (optind
+ 1 < argc
) {
7840 log_error("Too many arguments.");
7844 if (strlen(argv
[optind
]) != 1) {
7845 log_error("Expected single character argument.");
7849 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7850 if (table
[i
].from
== argv
[optind
][0])
7853 if (i
>= ELEMENTSOF(table
)) {
7854 log_error("Unknown command '%s'.", argv
[optind
]);
7858 arg_action
= table
[i
].to
;
7865 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7871 static const struct option options
[] = {
7872 { "help", no_argument
, NULL
, ARG_HELP
},
7881 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7892 assert_not_reached("Unhandled option");
7895 if (optind
< argc
) {
7896 log_error("Too many arguments.");
7903 static int parse_argv(int argc
, char *argv
[]) {
7907 if (program_invocation_short_name
) {
7909 if (strstr(program_invocation_short_name
, "halt")) {
7910 arg_action
= ACTION_HALT
;
7911 return halt_parse_argv(argc
, argv
);
7912 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7913 arg_action
= ACTION_POWEROFF
;
7914 return halt_parse_argv(argc
, argv
);
7915 } else if (strstr(program_invocation_short_name
, "reboot")) {
7917 arg_action
= ACTION_KEXEC
;
7919 arg_action
= ACTION_REBOOT
;
7920 return halt_parse_argv(argc
, argv
);
7921 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7922 arg_action
= ACTION_POWEROFF
;
7923 return shutdown_parse_argv(argc
, argv
);
7924 } else if (strstr(program_invocation_short_name
, "init")) {
7926 if (sd_booted() > 0) {
7927 arg_action
= _ACTION_INVALID
;
7928 return telinit_parse_argv(argc
, argv
);
7930 /* Hmm, so some other init system is
7931 * running, we need to forward this
7932 * request to it. For now we simply
7933 * guess that it is Upstart. */
7935 execv(TELINIT
, argv
);
7937 log_error("Couldn't find an alternative telinit implementation to spawn.");
7941 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7942 arg_action
= ACTION_RUNLEVEL
;
7943 return runlevel_parse_argv(argc
, argv
);
7947 arg_action
= ACTION_SYSTEMCTL
;
7948 return systemctl_parse_argv(argc
, argv
);
7951 #ifdef HAVE_SYSV_COMPAT
7952 _pure_
static int action_to_runlevel(void) {
7954 static const char table
[_ACTION_MAX
] = {
7955 [ACTION_HALT
] = '0',
7956 [ACTION_POWEROFF
] = '0',
7957 [ACTION_REBOOT
] = '6',
7958 [ACTION_RUNLEVEL2
] = '2',
7959 [ACTION_RUNLEVEL3
] = '3',
7960 [ACTION_RUNLEVEL4
] = '4',
7961 [ACTION_RUNLEVEL5
] = '5',
7962 [ACTION_RESCUE
] = '1'
7965 assert(arg_action
< _ACTION_MAX
);
7967 return table
[arg_action
];
7971 static int talk_initctl(void) {
7972 #ifdef HAVE_SYSV_COMPAT
7973 struct init_request request
= {
7974 .magic
= INIT_MAGIC
,
7976 .cmd
= INIT_CMD_RUNLVL
7979 _cleanup_close_
int fd
= -1;
7983 rl
= action_to_runlevel();
7987 request
.runlevel
= rl
;
7989 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7991 if (errno
== ENOENT
)
7994 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7997 r
= loop_write(fd
, &request
, sizeof(request
), false);
7999 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
8007 static int systemctl_main(int argc
, char *argv
[]) {
8009 static const Verb verbs
[] = {
8010 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
8011 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
8012 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
8013 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
8014 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
8015 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
8016 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, trivial_method
},
8017 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
8018 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8019 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8020 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8021 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8022 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8023 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8024 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8025 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
8026 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8027 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
8028 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8029 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
8030 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
8031 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
8032 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8033 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8034 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
8035 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8036 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
8037 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8038 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8039 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8040 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8041 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
8042 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8043 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8044 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
8045 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8046 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8047 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_system_special
},
8048 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8049 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8050 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8051 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8052 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
8053 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8054 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8055 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
8056 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
8057 { "enable", 2, VERB_ANY
, 0, enable_unit
},
8058 { "disable", 2, VERB_ANY
, 0, enable_unit
},
8059 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
8060 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
8061 { "preset", 2, VERB_ANY
, 0, enable_unit
},
8062 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
8063 { "mask", 2, VERB_ANY
, 0, enable_unit
},
8064 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
8065 { "link", 2, VERB_ANY
, 0, enable_unit
},
8066 { "revert", 2, VERB_ANY
, 0, enable_unit
},
8067 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
8068 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
8069 { "set-default", 2, 2, 0, set_default
},
8070 { "get-default", VERB_ANY
, 1, 0, get_default
},
8071 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
8072 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
8073 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
8074 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
8075 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
8079 return dispatch_verb(argc
, argv
, verbs
, NULL
);
8082 static int reload_with_fallback(void) {
8084 /* First, try systemd via D-Bus. */
8085 if (daemon_reload(0, NULL
, NULL
) >= 0)
8088 /* Nothing else worked, so let's try signals */
8089 assert(IN_SET(arg_action
, ACTION_RELOAD
, ACTION_REEXEC
));
8091 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
8092 return log_error_errno(errno
, "kill() failed: %m");
8097 static int start_with_fallback(void) {
8099 /* First, try systemd via D-Bus. */
8100 if (start_unit(0, NULL
, NULL
) >= 0)
8103 /* Nothing else worked, so let's try /dev/initctl */
8104 if (talk_initctl() > 0)
8107 log_error("Failed to talk to init daemon.");
8111 static int halt_now(enum action a
) {
8114 /* The kernel will automaticall flush ATA disks and suchlike
8115 * on reboot(), but the file systems need to be synce'd
8116 * explicitly in advance. */
8120 /* Make sure C-A-D is handled by the kernel from this point
8122 (void) reboot(RB_ENABLE_CAD
);
8127 log_info("Halting.");
8128 (void) reboot(RB_HALT_SYSTEM
);
8131 case ACTION_POWEROFF
:
8132 log_info("Powering off.");
8133 (void) reboot(RB_POWER_OFF
);
8137 case ACTION_REBOOT
: {
8138 _cleanup_free_
char *param
= NULL
;
8140 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
8142 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
8144 if (!isempty(param
)) {
8145 log_info("Rebooting with argument '%s'.", param
);
8146 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
8147 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
8150 log_info("Rebooting.");
8151 (void) reboot(RB_AUTOBOOT
);
8156 assert_not_reached("Unknown action.");
8160 static int logind_schedule_shutdown(void) {
8163 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8164 char date
[FORMAT_TIMESTAMP_MAX
];
8169 r
= acquire_bus(BUS_FULL
, &bus
);
8173 switch (arg_action
) {
8177 case ACTION_POWEROFF
:
8178 action
= "poweroff";
8193 action
= strjoina("dry-", action
);
8195 (void) logind_set_wall_message();
8197 r
= sd_bus_call_method(
8199 "org.freedesktop.login1",
8200 "/org/freedesktop/login1",
8201 "org.freedesktop.login1.Manager",
8209 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
8211 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
8214 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8219 static int halt_main(void) {
8222 r
= logind_check_inhibitors(arg_action
);
8227 return logind_schedule_shutdown();
8229 if (geteuid() != 0) {
8230 if (arg_dry
|| arg_force
> 0) {
8231 log_error("Must be root.");
8235 /* Try logind if we are a normal user and no special
8236 * mode applies. Maybe PolicyKit allows us to shutdown
8238 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
8239 r
= logind_reboot(arg_action
);
8242 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
8243 /* requested operation is not
8244 * supported on the local system or
8245 * already in progress */
8247 /* on all other errors, try low-level operation */
8251 if (!arg_dry
&& !arg_force
)
8252 return start_with_fallback();
8254 assert(geteuid() == 0);
8257 if (sd_booted() > 0)
8258 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8260 r
= utmp_put_shutdown();
8262 log_warning_errno(r
, "Failed to write utmp record: %m");
8269 r
= halt_now(arg_action
);
8270 return log_error_errno(r
, "Failed to reboot: %m");
8273 static int runlevel_main(void) {
8274 int r
, runlevel
, previous
;
8276 r
= utmp_get_runlevel(&runlevel
, &previous
);
8283 previous
<= 0 ? 'N' : previous
,
8284 runlevel
<= 0 ? 'N' : runlevel
);
8289 static int logind_cancel_shutdown(void) {
8291 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8295 r
= acquire_bus(BUS_FULL
, &bus
);
8299 (void) logind_set_wall_message();
8301 r
= sd_bus_call_method(
8303 "org.freedesktop.login1",
8304 "/org/freedesktop/login1",
8305 "org.freedesktop.login1.Manager",
8306 "CancelScheduledShutdown",
8310 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
8314 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8319 int main(int argc
, char*argv
[]) {
8322 setlocale(LC_ALL
, "");
8323 log_parse_environment();
8327 /* Explicitly not on_tty() to avoid setting cached value.
8328 * This becomes relevant for piping output which might be
8330 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
8332 r
= parse_argv(argc
, argv
);
8336 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
8337 log_info("Running in chroot, ignoring request.");
8342 /* systemctl_main() will print an error message for the bus
8343 * connection, but only if it needs to */
8345 switch (arg_action
) {
8347 case ACTION_SYSTEMCTL
:
8348 r
= systemctl_main(argc
, argv
);
8352 case ACTION_POWEROFF
:
8358 case ACTION_RUNLEVEL2
:
8359 case ACTION_RUNLEVEL3
:
8360 case ACTION_RUNLEVEL4
:
8361 case ACTION_RUNLEVEL5
:
8363 case ACTION_EMERGENCY
:
8364 case ACTION_DEFAULT
:
8365 r
= start_with_fallback();
8370 r
= reload_with_fallback();
8373 case ACTION_CANCEL_SHUTDOWN
:
8374 r
= logind_cancel_shutdown();
8377 case ACTION_RUNLEVEL
:
8378 r
= runlevel_main();
8381 case _ACTION_INVALID
:
8383 assert_not_reached("Unknown action");
8390 ask_password_agent_close();
8391 polkit_agent_close();
8393 strv_free(arg_types
);
8394 strv_free(arg_states
);
8395 strv_free(arg_properties
);
8397 strv_free(arg_wall
);
8400 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8401 return r
< 0 ? EXIT_FAILURE
: r
;