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
, desc_len
, max_desc_len
;
415 unsigned n_shown
= 0;
418 max_id_len
= strlen("UNIT");
419 load_len
= strlen("LOAD");
420 active_len
= strlen("ACTIVE");
421 sub_len
= strlen("SUB");
422 job_len
= strlen("JOB");
423 max_desc_len
= strlen("DESCRIPTION");
425 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
426 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
427 load_len
= MAX(load_len
, strlen(u
->load_state
));
428 active_len
= MAX(active_len
, strlen(u
->active_state
));
429 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
430 max_desc_len
= MAX(max_desc_len
, strlen(u
->description
));
432 if (u
->job_id
!= 0) {
433 job_len
= MAX(job_len
, strlen(u
->job_type
));
437 if (!arg_no_legend
&&
438 (streq(u
->active_state
, "failed") ||
439 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
443 if (!arg_full
&& original_stdout_is_tty
) {
446 id_len
= MIN(max_id_len
, 25u); /* as much as it needs, but at most 25 for now */
447 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
450 basic_len
+= job_len
+ 1;
452 if (basic_len
< (unsigned) columns()) {
453 unsigned extra_len
, incr
;
454 extra_len
= columns() - basic_len
;
456 /* Either UNIT already got 25, or is fully satisfied.
457 * Grant up to 25 to DESC now. */
458 incr
= MIN(extra_len
, 25u);
462 /* Of the remainder give as much as the ID needs to the ID, and give the rest to the
463 * description but not more than it needs. */
465 incr
= MIN(max_id_len
- id_len
, extra_len
);
467 desc_len
+= MIN(extra_len
- incr
, max_desc_len
- desc_len
);
472 desc_len
= max_desc_len
;
475 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
476 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
477 const char *on_underline
= "", *off_underline
= "";
478 const char *on_loaded
= "", *off_loaded
= "";
479 const char *on_active
= "", *off_active
= "";
480 const char *on_circle
= "", *off_circle
= "";
482 bool circle
= false, underline
= false;
484 if (!n_shown
&& !arg_no_legend
) {
489 printf("%s%-*s %-*s %-*s %-*s ",
493 active_len
, "ACTIVE",
497 printf("%-*s ", job_len
, "JOB");
501 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
508 if (u
+ 1 < unit_infos
+ c
&&
509 !streq(unit_type_suffix(u
->id
), unit_type_suffix((u
+ 1)->id
))) {
510 on_underline
= ansi_underline();
511 off_underline
= ansi_normal();
515 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
516 on_circle
= ansi_highlight_yellow();
517 off_circle
= ansi_normal();
519 on_loaded
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
520 off_loaded
= underline
? on_underline
: ansi_normal();
521 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
522 on_circle
= ansi_highlight_red();
523 off_circle
= ansi_normal();
525 on_active
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
526 off_active
= underline
? on_underline
: ansi_normal();
530 j
= strjoin(u
->machine
, ":", u
->id
);
539 e
= ellipsize(id
, id_len
, 33);
547 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
549 printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
551 on_active
, id_len
, id
, off_active
,
552 on_loaded
, load_len
, u
->load_state
, off_loaded
,
553 on_active
, active_len
, u
->active_state
,
554 sub_len
, u
->sub_state
, off_active
,
555 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
559 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
564 if (!arg_no_legend
) {
565 const char *on
, *off
;
569 "LOAD = Reflects whether the unit definition was properly loaded.\n"
570 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
571 "SUB = The low-level unit activation state, values depend on unit type.");
572 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
573 on
= ansi_highlight();
576 on
= ansi_highlight_red();
581 printf("%s%u loaded units listed.%s\n"
582 "To show all installed unit files use 'systemctl list-unit-files'.\n",
585 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
586 "To show all installed unit files use 'systemctl list-unit-files'.\n",
593 static int get_unit_list(
597 UnitInfo
**unit_infos
,
599 sd_bus_message
**_reply
) {
601 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
602 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
603 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
607 bool fallback
= false;
613 r
= sd_bus_message_new_method_call(
616 "org.freedesktop.systemd1",
617 "/org/freedesktop/systemd1",
618 "org.freedesktop.systemd1.Manager",
619 "ListUnitsByPatterns");
621 return bus_log_create_error(r
);
623 r
= sd_bus_message_append_strv(m
, arg_states
);
625 return bus_log_create_error(r
);
627 r
= sd_bus_message_append_strv(m
, patterns
);
629 return bus_log_create_error(r
);
631 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
632 if (r
< 0 && (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
) ||
633 sd_bus_error_has_name(&error
, SD_BUS_ERROR_ACCESS_DENIED
))) {
634 /* Fallback to legacy ListUnitsFiltered method */
636 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
637 m
= sd_bus_message_unref(m
);
638 sd_bus_error_free(&error
);
640 r
= sd_bus_message_new_method_call(
643 "org.freedesktop.systemd1",
644 "/org/freedesktop/systemd1",
645 "org.freedesktop.systemd1.Manager",
646 "ListUnitsFiltered");
648 return bus_log_create_error(r
);
650 r
= sd_bus_message_append_strv(m
, arg_states
);
652 return bus_log_create_error(r
);
654 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
657 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
659 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
661 return bus_log_parse_error(r
);
663 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
666 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
669 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
672 (*unit_infos
)[c
++] = u
;
675 return bus_log_parse_error(r
);
677 r
= sd_bus_message_exit_container(reply
);
679 return bus_log_parse_error(r
);
687 static void message_set_freep(Set
**set
) {
690 while ((m
= set_steal_first(*set
)))
691 sd_bus_message_unref(m
);
696 static int get_unit_list_recursive(
699 UnitInfo
**_unit_infos
,
703 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
704 _cleanup_(message_set_freep
) Set
*replies
;
705 sd_bus_message
*reply
;
713 replies
= set_new(NULL
);
717 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
721 r
= set_put(replies
, reply
);
723 sd_bus_message_unref(reply
);
728 _cleanup_strv_free_
char **machines
= NULL
;
731 r
= sd_get_machine_names(&machines
);
733 return log_error_errno(r
, "Failed to get machine names: %m");
735 STRV_FOREACH(i
, machines
) {
736 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
739 r
= sd_bus_open_system_machine(&container
, *i
);
741 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
745 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
751 r
= set_put(replies
, reply
);
753 sd_bus_message_unref(reply
);
758 *_machines
= machines
;
763 *_unit_infos
= unit_infos
;
772 static int list_units(int argc
, char *argv
[], void *userdata
) {
773 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
774 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
775 _cleanup_strv_free_
char **machines
= NULL
;
779 r
= acquire_bus(BUS_MANAGER
, &bus
);
783 pager_open(arg_no_pager
, false);
785 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
789 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
790 return output_units_list(unit_infos
, r
);
793 static int get_triggered_units(
798 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
805 r
= sd_bus_get_property_strv(
807 "org.freedesktop.systemd1",
809 "org.freedesktop.systemd1.Unit",
814 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
819 static int get_listening(
821 const char* unit_path
,
824 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
825 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
826 const char *type
, *path
;
829 r
= sd_bus_get_property(
831 "org.freedesktop.systemd1",
833 "org.freedesktop.systemd1.Socket",
839 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
841 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
843 return bus_log_parse_error(r
);
845 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
847 r
= strv_extend(listening
, type
);
851 r
= strv_extend(listening
, path
);
858 return bus_log_parse_error(r
);
860 r
= sd_bus_message_exit_container(reply
);
862 return bus_log_parse_error(r
);
874 /* Note: triggered is a list here, although it almost certainly
875 * will always be one unit. Nevertheless, dbus API allows for multiple
876 * values, so let's follow that. */
879 /* The strv above is shared. free is set only in the first one. */
883 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
889 if (!a
->machine
&& b
->machine
)
891 if (a
->machine
&& !b
->machine
)
893 if (a
->machine
&& b
->machine
) {
894 o
= strcasecmp(a
->machine
, b
->machine
);
899 o
= strcmp(a
->path
, b
->path
);
901 o
= strcmp(a
->type
, b
->type
);
906 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
907 struct socket_info
*s
;
908 unsigned pathlen
= strlen("LISTEN"),
909 typelen
= strlen("TYPE") * arg_show_types
,
910 socklen
= strlen("UNIT"),
911 servlen
= strlen("ACTIVATES");
912 const char *on
, *off
;
914 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
918 socklen
= MAX(socklen
, strlen(s
->id
));
920 typelen
= MAX(typelen
, strlen(s
->type
));
921 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
923 STRV_FOREACH(a
, s
->triggered
)
924 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
925 servlen
= MAX(servlen
, tmp
);
930 printf("%-*s %-*.*s%-*s %s\n",
932 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
936 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
937 _cleanup_free_
char *j
= NULL
;
942 j
= strjoin(s
->machine
, ":", s
->path
);
950 printf("%-*s %-*s %-*s",
951 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
954 pathlen
, path
, socklen
, s
->id
);
955 STRV_FOREACH(a
, s
->triggered
)
957 a
== s
->triggered
? "" : ",", *a
);
961 on
= ansi_highlight();
966 on
= ansi_highlight_red();
970 if (!arg_no_legend
) {
971 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
973 printf("Pass --all to see loaded but inactive sockets, too.\n");
979 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
980 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
981 _cleanup_strv_free_
char **machines
= NULL
;
982 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
983 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
985 struct socket_info
*s
;
991 r
= acquire_bus(BUS_MANAGER
, &bus
);
995 pager_open(arg_no_pager
, false);
997 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1001 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1002 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
1005 if (!endswith(u
->id
, ".socket"))
1008 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1012 c
= get_listening(bus
, u
->unit_path
, &listening
);
1018 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
1023 for (i
= 0; i
< c
; i
++)
1024 socket_infos
[cs
+ i
] = (struct socket_info
) {
1025 .machine
= u
->machine
,
1027 .type
= listening
[i
*2],
1028 .path
= listening
[i
*2 + 1],
1029 .triggered
= triggered
,
1030 .own_triggered
= i
==0,
1033 /* from this point on we will cleanup those socket_infos */
1036 listening
= triggered
= NULL
; /* avoid cleanup */
1039 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
1040 (__compar_fn_t
) socket_info_compare
);
1042 output_sockets_list(socket_infos
, cs
);
1045 assert(cs
== 0 || socket_infos
);
1046 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
1049 if (s
->own_triggered
)
1050 strv_free(s
->triggered
);
1056 static int get_next_elapse(
1059 dual_timestamp
*next
) {
1061 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1069 r
= sd_bus_get_property_trivial(
1071 "org.freedesktop.systemd1",
1073 "org.freedesktop.systemd1.Timer",
1074 "NextElapseUSecMonotonic",
1079 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1081 r
= sd_bus_get_property_trivial(
1083 "org.freedesktop.systemd1",
1085 "org.freedesktop.systemd1.Timer",
1086 "NextElapseUSecRealtime",
1091 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1097 static int get_last_trigger(
1102 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1109 r
= sd_bus_get_property_trivial(
1111 "org.freedesktop.systemd1",
1113 "org.freedesktop.systemd1.Timer",
1119 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1125 const char* machine
;
1128 usec_t last_trigger
;
1132 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1138 if (!a
->machine
&& b
->machine
)
1140 if (a
->machine
&& !b
->machine
)
1142 if (a
->machine
&& b
->machine
) {
1143 o
= strcasecmp(a
->machine
, b
->machine
);
1148 if (a
->next_elapse
< b
->next_elapse
)
1150 if (a
->next_elapse
> b
->next_elapse
)
1153 return strcmp(a
->id
, b
->id
);
1156 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1157 struct timer_info
*t
;
1159 nextlen
= strlen("NEXT"),
1160 leftlen
= strlen("LEFT"),
1161 lastlen
= strlen("LAST"),
1162 passedlen
= strlen("PASSED"),
1163 unitlen
= strlen("UNIT"),
1164 activatelen
= strlen("ACTIVATES");
1166 const char *on
, *off
;
1168 assert(timer_infos
|| n
== 0);
1170 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1174 if (t
->next_elapse
> 0) {
1175 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1177 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1178 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1180 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1181 leftlen
= MAX(leftlen
, strlen(trel
));
1184 if (t
->last_trigger
> 0) {
1185 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1187 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1188 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1190 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1191 passedlen
= MAX(passedlen
, strlen(trel
));
1194 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1196 STRV_FOREACH(a
, t
->triggered
)
1197 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1199 activatelen
= MAX(activatelen
, ul
);
1204 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1208 passedlen
, "PASSED",
1212 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1213 _cleanup_free_
char *j
= NULL
;
1215 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1216 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1219 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1220 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1222 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1223 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1226 j
= strjoin(t
->machine
, ":", t
->id
);
1233 printf("%-*s %-*s %-*s %-*s %-*s",
1234 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1236 STRV_FOREACH(a
, t
->triggered
)
1238 a
== t
->triggered
? "" : ",", *a
);
1242 on
= ansi_highlight();
1243 off
= ansi_normal();
1247 on
= ansi_highlight_red();
1248 off
= ansi_normal();
1251 if (!arg_no_legend
) {
1252 printf("%s%u timers listed.%s\n", on
, n
, off
);
1254 printf("Pass --all to see loaded but inactive timers, too.\n");
1260 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1266 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1269 if (next
->monotonic
> nw
->monotonic
)
1270 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1272 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1274 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1275 next_elapse
= MIN(converted
, next
->realtime
);
1277 next_elapse
= converted
;
1280 next_elapse
= next
->realtime
;
1285 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1286 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1287 _cleanup_strv_free_
char **machines
= NULL
;
1288 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1289 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1290 struct timer_info
*t
;
1298 r
= acquire_bus(BUS_MANAGER
, &bus
);
1302 pager_open(arg_no_pager
, false);
1304 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1308 dual_timestamp_get(&nw
);
1310 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1311 _cleanup_strv_free_
char **triggered
= NULL
;
1312 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1315 if (!endswith(u
->id
, ".timer"))
1318 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1322 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1326 get_last_trigger(bus
, u
->unit_path
, &last
);
1328 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1333 m
= calc_next_elapse(&nw
, &next
);
1335 timer_infos
[c
++] = (struct timer_info
) {
1336 .machine
= u
->machine
,
1339 .last_trigger
= last
,
1340 .triggered
= triggered
,
1343 triggered
= NULL
; /* avoid cleanup */
1346 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1347 (__compar_fn_t
) timer_info_compare
);
1349 output_timers_list(timer_infos
, c
);
1352 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1353 strv_free(t
->triggered
);
1358 static int compare_unit_file_list(const void *a
, const void *b
) {
1359 const char *d1
, *d2
;
1360 const UnitFileList
*u
= a
, *v
= b
;
1362 d1
= strrchr(u
->path
, '.');
1363 d2
= strrchr(v
->path
, '.');
1368 r
= strcasecmp(d1
, d2
);
1373 return strcasecmp(basename(u
->path
), basename(v
->path
));
1376 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1379 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1382 if (!strv_isempty(arg_types
)) {
1385 dot
= strrchr(u
->path
, '.');
1389 if (!strv_find(arg_types
, dot
+1))
1393 if (!strv_isempty(states
) &&
1394 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1400 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1401 unsigned max_id_len
, id_cols
, state_cols
;
1402 const UnitFileList
*u
;
1404 max_id_len
= strlen("UNIT FILE");
1405 state_cols
= strlen("STATE");
1407 for (u
= units
; u
< units
+ c
; u
++) {
1408 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1409 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1413 unsigned basic_cols
;
1415 id_cols
= MIN(max_id_len
, 25u);
1416 basic_cols
= 1 + id_cols
+ state_cols
;
1417 if (basic_cols
< (unsigned) columns())
1418 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1420 id_cols
= max_id_len
;
1422 if (!arg_no_legend
&& c
> 0)
1423 printf("%s%-*s %-*s%s\n",
1425 id_cols
, "UNIT FILE",
1426 state_cols
, "STATE",
1429 for (u
= units
; u
< units
+ c
; u
++) {
1430 _cleanup_free_
char *e
= NULL
;
1431 const char *on
, *off
, *on_underline
= "", *off_underline
= "";
1433 bool underline
= false;
1435 if (u
+ 1 < units
+ c
&&
1436 !streq(unit_type_suffix(u
->path
), unit_type_suffix((u
+ 1)->path
))) {
1437 on_underline
= ansi_underline();
1438 off_underline
= ansi_normal();
1442 if (IN_SET(u
->state
,
1444 UNIT_FILE_MASKED_RUNTIME
,
1447 on
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
1448 else if (u
->state
== UNIT_FILE_ENABLED
)
1449 on
= underline
? ansi_highlight_green_underline() : ansi_highlight_green();
1452 off
= off_underline
;
1454 id
= basename(u
->path
);
1456 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1458 printf("%s%-*s %s%-*s%s%s\n",
1460 id_cols
, e
? e
: id
,
1461 on
, state_cols
, unit_file_state_to_string(u
->state
), off
,
1466 printf("\n%u unit files listed.\n", c
);
1469 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1470 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1471 _cleanup_free_ UnitFileList
*units
= NULL
;
1478 bool fallback
= false;
1480 if (install_client_side()) {
1486 h
= hashmap_new(&string_hash_ops
);
1490 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1492 unit_file_list_free(h
);
1493 return log_error_errno(r
, "Failed to get unit file list: %m");
1496 n_units
= hashmap_size(h
);
1498 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1500 unit_file_list_free(h
);
1504 HASHMAP_FOREACH(u
, h
, i
) {
1505 if (!output_show_unit_file(u
, NULL
, NULL
))
1512 assert(c
<= n_units
);
1517 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1518 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1521 r
= acquire_bus(BUS_MANAGER
, &bus
);
1525 r
= sd_bus_message_new_method_call(
1528 "org.freedesktop.systemd1",
1529 "/org/freedesktop/systemd1",
1530 "org.freedesktop.systemd1.Manager",
1531 "ListUnitFilesByPatterns");
1533 return bus_log_create_error(r
);
1535 r
= sd_bus_message_append_strv(m
, arg_states
);
1537 return bus_log_create_error(r
);
1539 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1541 return bus_log_create_error(r
);
1543 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1544 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1545 /* Fallback to legacy ListUnitFiles method */
1547 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1548 m
= sd_bus_message_unref(m
);
1549 sd_bus_error_free(&error
);
1551 r
= sd_bus_message_new_method_call(
1554 "org.freedesktop.systemd1",
1555 "/org/freedesktop/systemd1",
1556 "org.freedesktop.systemd1.Manager",
1559 return bus_log_create_error(r
);
1561 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1564 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1566 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1568 return bus_log_parse_error(r
);
1570 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1572 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1575 units
[c
] = (struct UnitFileList
) {
1577 unit_file_state_from_string(state
)
1580 if (output_show_unit_file(&units
[c
],
1581 fallback
? arg_states
: NULL
,
1582 fallback
? strv_skip(argv
, 1) : NULL
))
1587 return bus_log_parse_error(r
);
1589 r
= sd_bus_message_exit_container(reply
);
1591 return bus_log_parse_error(r
);
1594 pager_open(arg_no_pager
, false);
1596 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1597 output_unit_file_list(units
, c
);
1599 if (install_client_side())
1600 for (unit
= units
; unit
< units
+ c
; unit
++)
1606 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1607 _cleanup_free_
char *n
= NULL
;
1608 size_t max_len
= MAX(columns(),20u);
1614 for (i
= level
- 1; i
>= 0; i
--) {
1616 if (len
> max_len
- 3 && !arg_full
) {
1617 printf("%s...\n",max_len
% 2 ? "" : " ");
1620 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1624 if (len
> max_len
- 3 && !arg_full
) {
1625 printf("%s...\n",max_len
% 2 ? "" : " ");
1629 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1633 printf("%s\n", name
);
1637 n
= ellipsize(name
, max_len
-len
, 100);
1645 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1647 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1648 [DEPENDENCY_FORWARD
] = "Requires\0"
1653 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1658 [DEPENDENCY_AFTER
] = "After\0",
1659 [DEPENDENCY_BEFORE
] = "Before\0",
1662 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1663 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1664 _cleanup_strv_free_
char **ret
= NULL
;
1665 _cleanup_free_
char *path
= NULL
;
1671 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1673 path
= unit_dbus_path_from_name(name
);
1677 r
= sd_bus_call_method(
1679 "org.freedesktop.systemd1",
1681 "org.freedesktop.DBus.Properties",
1685 "s", "org.freedesktop.systemd1.Unit");
1687 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1689 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1691 return bus_log_parse_error(r
);
1693 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1696 r
= sd_bus_message_read(reply
, "s", &prop
);
1698 return bus_log_parse_error(r
);
1700 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1701 r
= sd_bus_message_skip(reply
, "v");
1703 return bus_log_parse_error(r
);
1706 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1708 return bus_log_parse_error(r
);
1710 r
= bus_message_read_strv_extend(reply
, &ret
);
1712 return bus_log_parse_error(r
);
1714 r
= sd_bus_message_exit_container(reply
);
1716 return bus_log_parse_error(r
);
1719 r
= sd_bus_message_exit_container(reply
);
1721 return bus_log_parse_error(r
);
1725 return bus_log_parse_error(r
);
1727 r
= sd_bus_message_exit_container(reply
);
1729 return bus_log_parse_error(r
);
1737 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1738 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1740 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1742 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1745 return strcasecmp(*a
, *b
);
1748 static int list_dependencies_one(
1753 unsigned int branches
) {
1755 _cleanup_strv_free_
char **deps
= NULL
;
1763 r
= strv_extend(units
, name
);
1767 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1771 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1773 STRV_FOREACH(c
, deps
) {
1774 if (strv_contains(*units
, *c
)) {
1776 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1786 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1789 (void) get_state_one_unit(bus
, *c
, &active_state
);
1791 switch (active_state
) {
1793 case UNIT_RELOADING
:
1794 case UNIT_ACTIVATING
:
1795 on
= ansi_highlight_green();
1799 case UNIT_DEACTIVATING
:
1804 on
= ansi_highlight_red();
1808 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1811 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1815 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1816 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1823 strv_remove(*units
, name
);
1828 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1829 _cleanup_strv_free_
char **units
= NULL
;
1830 _cleanup_free_
char *unit
= NULL
;
1836 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1838 return log_error_errno(r
, "Failed to mangle unit name: %m");
1842 u
= SPECIAL_DEFAULT_TARGET
;
1844 r
= acquire_bus(BUS_MANAGER
, &bus
);
1848 pager_open(arg_no_pager
, false);
1852 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1855 struct machine_info
{
1859 char *control_group
;
1860 uint32_t n_failed_units
;
1865 static const struct bus_properties_map machine_info_property_map
[] = {
1866 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1867 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1868 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1869 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1870 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1874 static void machine_info_clear(struct machine_info
*info
) {
1879 free(info
->control_group
);
1883 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1889 for (i
= 0; i
< n
; i
++)
1890 machine_info_clear(&machine_infos
[i
]);
1892 free(machine_infos
);
1895 static int compare_machine_info(const void *a
, const void *b
) {
1896 const struct machine_info
*u
= a
, *v
= b
;
1898 if (u
->is_host
!= v
->is_host
)
1899 return u
->is_host
> v
->is_host
? -1 : 1;
1901 return strcasecmp(u
->name
, v
->name
);
1904 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1905 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1911 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1918 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1925 static bool output_show_machine(const char *name
, char **patterns
) {
1926 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1929 static int get_machine_list(
1931 struct machine_info
**_machine_infos
,
1934 struct machine_info
*machine_infos
= NULL
;
1935 _cleanup_strv_free_
char **m
= NULL
;
1936 _cleanup_free_
char *hn
= NULL
;
1941 hn
= gethostname_malloc();
1945 if (output_show_machine(hn
, patterns
)) {
1946 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1949 machine_infos
[c
].is_host
= true;
1950 machine_infos
[c
].name
= hn
;
1953 get_machine_properties(bus
, &machine_infos
[c
]);
1957 r
= sd_get_machine_names(&m
);
1959 return log_error_errno(r
, "Failed to get machine list: %m");
1961 STRV_FOREACH(i
, m
) {
1962 _cleanup_free_
char *class = NULL
;
1964 if (!output_show_machine(*i
, patterns
))
1967 sd_machine_get_class(*i
, &class);
1968 if (!streq_ptr(class, "container"))
1971 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1972 free_machines_list(machine_infos
, c
);
1976 machine_infos
[c
].is_host
= false;
1977 machine_infos
[c
].name
= strdup(*i
);
1978 if (!machine_infos
[c
].name
) {
1979 free_machines_list(machine_infos
, c
);
1983 get_machine_properties(NULL
, &machine_infos
[c
]);
1987 *_machine_infos
= machine_infos
;
1991 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1992 struct machine_info
*m
;
1995 namelen
= sizeof("NAME") - 1,
1996 statelen
= sizeof("STATE") - 1,
1997 failedlen
= sizeof("FAILED") - 1,
1998 jobslen
= sizeof("JOBS") - 1;
2000 assert(machine_infos
|| n
== 0);
2002 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2003 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
2004 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
2005 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
2006 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
2008 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
2012 if (!arg_no_legend
) {
2016 printf("%-*s %-*s %-*s %-*s\n",
2019 failedlen
, "FAILED",
2023 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2024 const char *on_state
= "", *off_state
= "";
2025 const char *on_failed
= "", *off_failed
= "";
2026 bool circle
= false;
2028 if (streq_ptr(m
->state
, "degraded")) {
2029 on_state
= ansi_highlight_red();
2030 off_state
= ansi_normal();
2032 } else if (!streq_ptr(m
->state
, "running")) {
2033 on_state
= ansi_highlight_yellow();
2034 off_state
= ansi_normal();
2038 if (m
->n_failed_units
> 0) {
2039 on_failed
= ansi_highlight_red();
2040 off_failed
= ansi_normal();
2042 on_failed
= off_failed
= "";
2045 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
2048 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2049 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
2050 on_state
, statelen
, strna(m
->state
), off_state
,
2051 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2052 jobslen
, m
->n_jobs
);
2054 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2055 namelen
, strna(m
->name
),
2056 on_state
, statelen
, strna(m
->state
), off_state
,
2057 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2058 jobslen
, m
->n_jobs
);
2062 printf("\n%u machines listed.\n", n
);
2065 static int list_machines(int argc
, char *argv
[], void *userdata
) {
2066 struct machine_info
*machine_infos
= NULL
;
2070 if (geteuid() != 0) {
2071 log_error("Must be root.");
2075 r
= acquire_bus(BUS_MANAGER
, &bus
);
2079 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2083 pager_open(arg_no_pager
, false);
2085 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2086 output_machines_list(machine_infos
, r
);
2087 free_machines_list(machine_infos
, r
);
2092 static int get_default(int argc
, char *argv
[], void *userdata
) {
2093 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2094 _cleanup_free_
char *_path
= NULL
;
2098 if (install_client_side()) {
2099 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2101 return log_error_errno(r
, "Failed to get default target: %m");
2106 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2109 r
= acquire_bus(BUS_MANAGER
, &bus
);
2113 r
= sd_bus_call_method(
2115 "org.freedesktop.systemd1",
2116 "/org/freedesktop/systemd1",
2117 "org.freedesktop.systemd1.Manager",
2123 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2125 r
= sd_bus_message_read(reply
, "s", &path
);
2127 return bus_log_parse_error(r
);
2131 printf("%s\n", path
);
2136 static int set_default(int argc
, char *argv
[], void *userdata
) {
2137 _cleanup_free_
char *unit
= NULL
;
2138 UnitFileChange
*changes
= NULL
;
2139 unsigned n_changes
= 0;
2145 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2147 return log_error_errno(r
, "Failed to mangle unit name: %m");
2149 if (install_client_side()) {
2150 r
= unit_file_set_default(arg_scope
, UNIT_FILE_FORCE
, arg_root
, unit
, &changes
, &n_changes
);
2151 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2156 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2157 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2160 polkit_agent_open_if_enabled();
2162 r
= acquire_bus(BUS_MANAGER
, &bus
);
2166 r
= sd_bus_call_method(
2168 "org.freedesktop.systemd1",
2169 "/org/freedesktop/systemd1",
2170 "org.freedesktop.systemd1.Manager",
2176 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2178 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2182 /* Try to reload if enabled */
2184 r
= daemon_reload(argc
, argv
, userdata
);
2190 unit_file_changes_free(changes
, n_changes
);
2197 const char *name
, *type
, *state
;
2200 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2201 unsigned id_len
, unit_len
, type_len
, state_len
;
2202 const struct job_info
*j
;
2203 const char *on
, *off
;
2204 bool shorten
= false;
2206 assert(n
== 0 || jobs
);
2209 if (!arg_no_legend
) {
2210 on
= ansi_highlight_green();
2211 off
= ansi_normal();
2213 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2218 pager_open(arg_no_pager
, false);
2220 id_len
= strlen("JOB");
2221 unit_len
= strlen("UNIT");
2222 type_len
= strlen("TYPE");
2223 state_len
= strlen("STATE");
2225 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2226 uint32_t id
= j
->id
;
2227 assert(j
->name
&& j
->type
&& j
->state
);
2229 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2230 unit_len
= MAX(unit_len
, strlen(j
->name
));
2231 type_len
= MAX(type_len
, strlen(j
->type
));
2232 state_len
= MAX(state_len
, strlen(j
->state
));
2235 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2236 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2241 printf("%*s %-*s %-*s %-*s\n",
2245 state_len
, "STATE");
2247 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2248 _cleanup_free_
char *e
= NULL
;
2250 if (streq(j
->state
, "running")) {
2251 on
= ansi_highlight();
2252 off
= ansi_normal();
2256 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2257 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2259 on
, unit_len
, e
? e
: j
->name
, off
,
2261 on
, state_len
, j
->state
, off
);
2264 if (!arg_no_legend
) {
2265 on
= ansi_highlight();
2266 off
= ansi_normal();
2268 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2272 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2273 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2276 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2277 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2278 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2279 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2280 _cleanup_free_
struct job_info
*jobs
= NULL
;
2286 bool skipped
= false;
2288 r
= acquire_bus(BUS_MANAGER
, &bus
);
2292 r
= sd_bus_call_method(
2294 "org.freedesktop.systemd1",
2295 "/org/freedesktop/systemd1",
2296 "org.freedesktop.systemd1.Manager",
2302 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2304 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2306 return bus_log_parse_error(r
);
2308 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2309 struct job_info job
= { id
, name
, type
, state
};
2311 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2316 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2322 return bus_log_parse_error(r
);
2324 r
= sd_bus_message_exit_container(reply
);
2326 return bus_log_parse_error(r
);
2328 pager_open(arg_no_pager
, false);
2330 output_jobs_list(jobs
, c
, skipped
);
2334 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2340 return trivial_method(argc
, argv
, userdata
);
2342 r
= acquire_bus(BUS_MANAGER
, &bus
);
2346 polkit_agent_open_if_enabled();
2348 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2349 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2353 q
= safe_atou32(*name
, &id
);
2355 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2357 q
= sd_bus_call_method(
2359 "org.freedesktop.systemd1",
2360 "/org/freedesktop/systemd1",
2361 "org.freedesktop.systemd1.Manager",
2367 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2376 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2377 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2381 /* We ignore all errors here, since this is used to show a
2384 /* We don't use unit_dbus_path_from_name() directly since we
2385 * don't want to load the unit if it isn't loaded. */
2387 r
= sd_bus_call_method(
2389 "org.freedesktop.systemd1",
2390 "/org/freedesktop/systemd1",
2391 "org.freedesktop.systemd1.Manager",
2399 r
= sd_bus_message_read(reply
, "o", &path
);
2403 r
= sd_bus_get_property_trivial(
2405 "org.freedesktop.systemd1",
2407 "org.freedesktop.systemd1.Unit",
2417 static void warn_unit_file_changed(const char *name
) {
2420 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2421 ansi_highlight_red(),
2424 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2427 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2434 STRV_FOREACH(p
, lp
->search_path
) {
2435 _cleanup_free_
char *path
;
2437 path
= path_join(arg_root
, *p
, unit_name
);
2441 if (access(path
, F_OK
) == 0) {
2451 static int unit_find_paths(
2453 const char *unit_name
,
2455 char **fragment_path
,
2456 char ***dropin_paths
) {
2458 _cleanup_free_
char *path
= NULL
;
2459 _cleanup_strv_free_
char **dropins
= NULL
;
2463 * Finds where the unit is defined on disk. Returns 0 if the unit
2464 * is not found. Returns 1 if it is found, and sets
2465 * - the path to the unit in *path, if it exists on disk,
2466 * - and a strv of existing drop-ins in *dropins,
2467 * if the arg is not NULL and any dropins were found.
2471 assert(fragment_path
);
2474 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2475 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2476 _cleanup_free_
char *unit
= NULL
;
2478 unit
= unit_dbus_path_from_name(unit_name
);
2482 r
= sd_bus_get_property_string(
2484 "org.freedesktop.systemd1",
2486 "org.freedesktop.systemd1.Unit",
2491 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2494 r
= sd_bus_get_property_strv(
2496 "org.freedesktop.systemd1",
2498 "org.freedesktop.systemd1.Unit",
2503 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2506 _cleanup_set_free_ Set
*names
;
2508 names
= set_new(NULL
);
2512 r
= set_put(names
, unit_name
);
2514 return log_error_errno(r
, "Failed to add unit name: %m");
2516 r
= unit_file_find_path(lp
, unit_name
, &path
);
2521 _cleanup_free_
char *template = NULL
;
2523 r
= unit_name_template(unit_name
, &template);
2524 if (r
< 0 && r
!= -EINVAL
)
2525 return log_error_errno(r
, "Failed to determine template name: %m");
2527 r
= unit_file_find_path(lp
, template, &path
);
2534 r
= unit_file_find_dropin_paths(lp
->search_path
, NULL
, names
, &dropins
);
2542 if (!isempty(path
)) {
2543 *fragment_path
= path
;
2548 if (dropin_paths
&& !strv_isempty(dropins
)) {
2549 *dropin_paths
= dropins
;
2554 if (r
== 0 && !arg_force
)
2555 log_error("No files found for %s.", unit_name
);
2560 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2561 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2562 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2563 _cleanup_free_
char *buf
= NULL
;
2564 UnitActiveState state
;
2569 assert(active_state
);
2571 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2573 r
= sd_bus_call_method(
2575 "org.freedesktop.systemd1",
2576 "/org/freedesktop/systemd1",
2577 "org.freedesktop.systemd1.Manager",
2583 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2584 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2586 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2587 * considered inactive. */
2588 state
= UNIT_INACTIVE
;
2591 r
= sd_bus_message_read(reply
, "o", &path
);
2593 return bus_log_parse_error(r
);
2595 r
= sd_bus_get_property_string(
2597 "org.freedesktop.systemd1",
2599 "org.freedesktop.systemd1.Unit",
2604 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2606 state
= unit_active_state_from_string(buf
);
2607 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2608 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2613 *active_state
= state
;
2617 static int check_triggering_units(
2621 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2622 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2623 _cleanup_strv_free_
char **triggered_by
= NULL
;
2624 bool print_warning_label
= true;
2625 UnitActiveState active_state
;
2629 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2631 return log_error_errno(r
, "Failed to mangle unit name: %m");
2633 path
= unit_dbus_path_from_name(n
);
2637 r
= sd_bus_get_property_string(
2639 "org.freedesktop.systemd1",
2641 "org.freedesktop.systemd1.Unit",
2646 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2648 if (streq(load_state
, "masked"))
2651 r
= sd_bus_get_property_strv(
2653 "org.freedesktop.systemd1",
2655 "org.freedesktop.systemd1.Unit",
2660 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2662 STRV_FOREACH(i
, triggered_by
) {
2663 r
= get_state_one_unit(bus
, *i
, &active_state
);
2667 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2670 if (print_warning_label
) {
2671 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2672 print_warning_label
= false;
2675 log_warning(" %s", *i
);
2681 static const struct {
2684 } unit_actions
[] = {
2685 { "start", "StartUnit" },
2686 { "stop", "StopUnit" },
2687 { "condstop", "StopUnit" },
2688 { "reload", "ReloadUnit" },
2689 { "restart", "RestartUnit" },
2690 { "try-restart", "TryRestartUnit" },
2691 { "condrestart", "TryRestartUnit" },
2692 { "reload-or-restart", "ReloadOrRestartUnit" },
2693 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2694 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2695 { "condreload", "ReloadOrTryRestartUnit" },
2696 { "force-reload", "ReloadOrTryRestartUnit" }
2699 static const char *verb_to_method(const char *verb
) {
2702 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2703 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2704 return unit_actions
[i
].method
;
2709 static const char *method_to_verb(const char *method
) {
2712 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2713 if (streq_ptr(unit_actions
[i
].method
, method
))
2714 return unit_actions
[i
].verb
;
2726 static void wait_context_free(WaitContext
*c
) {
2727 c
->match
= sd_bus_slot_unref(c
->match
);
2728 c
->event
= sd_event_unref(c
->event
);
2729 c
->unit_paths
= set_free_free(c
->unit_paths
);
2732 static int on_properties_changed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
2733 WaitContext
*c
= userdata
;
2737 path
= sd_bus_message_get_path(m
);
2738 if (!set_contains(c
->unit_paths
, path
))
2741 /* Check if ActiveState changed to inactive/failed */
2742 /* (s interface, a{sv} changed_properties, as invalidated_properties) */
2743 r
= sd_bus_message_skip(m
, "s");
2745 return bus_log_parse_error(r
);
2747 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
2749 return bus_log_parse_error(r
);
2751 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
2754 r
= sd_bus_message_read(m
, "s", &s
);
2756 return bus_log_parse_error(r
);
2758 if (streq(s
, "ActiveState")) {
2761 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, "s");
2763 return bus_log_parse_error(r
);
2765 r
= sd_bus_message_read(m
, "s", &s
);
2767 return bus_log_parse_error(r
);
2769 is_failed
= streq(s
, "failed");
2770 if (streq(s
, "inactive") || is_failed
) {
2771 log_debug("%s became %s, dropping from --wait tracking", path
, s
);
2772 free(set_remove(c
->unit_paths
, path
));
2773 c
->any_failed
= c
->any_failed
|| is_failed
;
2775 log_debug("ActiveState on %s changed to %s", path
, s
);
2777 break; /* no need to dissect the rest of the message */
2779 /* other property */
2780 r
= sd_bus_message_skip(m
, "v");
2782 return bus_log_parse_error(r
);
2784 r
= sd_bus_message_exit_container(m
);
2786 return bus_log_parse_error(r
);
2789 return bus_log_parse_error(r
);
2791 if (set_isempty(c
->unit_paths
))
2792 sd_event_exit(c
->event
, EXIT_SUCCESS
);
2797 static int start_unit_one(
2802 sd_bus_error
*error
,
2804 WaitContext
*wait_context
) {
2806 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2816 _cleanup_free_
char *unit_path
= NULL
;
2819 log_debug("Watching for property changes of %s", name
);
2820 r
= sd_bus_call_method(
2822 "org.freedesktop.systemd1",
2823 "/org/freedesktop/systemd1",
2824 "org.freedesktop.systemd1.Manager",
2830 return log_error_errno(r
, "Failed to RefUnit %s: %s", name
, bus_error_message(error
, r
));
2832 unit_path
= unit_dbus_path_from_name(name
);
2836 r
= set_put_strdup(wait_context
->unit_paths
, unit_path
);
2838 return log_error_errno(r
, "Failed to add unit path %s to set: %m", unit_path
);
2840 mt
= strjoina("type='signal',"
2841 "interface='org.freedesktop.DBus.Properties',"
2842 "path='", unit_path
, "',"
2843 "member='PropertiesChanged'");
2844 r
= sd_bus_add_match(bus
, &wait_context
->match
, mt
, on_properties_changed
, wait_context
);
2846 return log_error_errno(r
, "Failed to add match for PropertiesChanged signal: %m");
2849 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2851 r
= sd_bus_call_method(
2853 "org.freedesktop.systemd1",
2854 "/org/freedesktop/systemd1",
2855 "org.freedesktop.systemd1.Manager",
2863 /* There's always a fallback possible for legacy actions. */
2864 if (arg_action
!= ACTION_SYSTEMCTL
)
2867 verb
= method_to_verb(method
);
2869 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2871 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2872 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2873 log_error("See %s logs and 'systemctl%s status%s %s' for details.",
2874 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2875 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2876 name
[0] == '-' ? " --" : "",
2882 r
= sd_bus_message_read(reply
, "o", &path
);
2884 return bus_log_parse_error(r
);
2886 if (need_daemon_reload(bus
, name
) > 0)
2887 warn_unit_file_changed(name
);
2890 log_debug("Adding %s to the set", path
);
2891 r
= bus_wait_for_jobs_add(w
, path
);
2899 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2900 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2907 STRV_FOREACH(name
, names
) {
2911 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2913 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2915 return log_error_errno(r
, "Failed to mangle name: %m");
2917 if (string_is_glob(t
))
2918 r
= strv_consume(&globs
, t
);
2920 r
= strv_consume(&mangled
, t
);
2925 /* Query the manager only if any of the names are a glob, since
2926 * this is fairly expensive */
2927 if (!strv_isempty(globs
)) {
2928 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2929 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2930 size_t allocated
, n
;
2932 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2936 n
= strv_length(mangled
);
2939 for (i
= 0; i
< r
; i
++) {
2940 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2943 mangled
[n
] = strdup(unit_infos
[i
].id
);
2947 mangled
[++n
] = NULL
;
2952 mangled
= NULL
; /* do not free */
2957 static const struct {
2961 } action_table
[_ACTION_MAX
] = {
2962 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2963 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2964 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2965 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2966 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2967 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2968 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2969 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2970 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2971 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2972 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2973 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2974 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2975 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2976 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2979 static enum action
verb_to_action(const char *verb
) {
2982 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2983 if (streq_ptr(action_table
[i
].verb
, verb
))
2986 return _ACTION_INVALID
;
2989 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2990 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2991 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2992 _cleanup_strv_free_
char **names
= NULL
;
2994 _cleanup_(wait_context_free
) WaitContext wait_context
= {};
2998 if (arg_wait
&& !strstr(argv
[0], "start")) {
2999 log_error("--wait may only be used with a command that starts units.");
3003 /* we cannot do sender tracking on the private bus, so we need the full
3004 * one for RefUnit to implement --wait */
3005 r
= acquire_bus(arg_wait
? BUS_FULL
: BUS_MANAGER
, &bus
);
3009 ask_password_agent_open_if_enabled();
3010 polkit_agent_open_if_enabled();
3012 if (arg_action
== ACTION_SYSTEMCTL
) {
3015 method
= verb_to_method(argv
[0]);
3016 action
= verb_to_action(argv
[0]);
3018 if (streq(argv
[0], "isolate")) {
3022 mode
= action_table
[action
].mode
?: arg_job_mode
;
3024 one_name
= action_table
[action
].target
;
3026 assert(arg_action
< ELEMENTSOF(action_table
));
3027 assert(action_table
[arg_action
].target
);
3029 method
= "StartUnit";
3031 mode
= action_table
[arg_action
].mode
;
3032 one_name
= action_table
[arg_action
].target
;
3036 names
= strv_new(one_name
, NULL
);
3038 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
3040 return log_error_errno(r
, "Failed to expand names: %m");
3043 if (!arg_no_block
) {
3044 r
= bus_wait_for_jobs_new(bus
, &w
);
3046 return log_error_errno(r
, "Could not watch jobs: %m");
3050 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3052 wait_context
.unit_paths
= set_new(&string_hash_ops
);
3053 if (!wait_context
.unit_paths
)
3056 r
= sd_bus_call_method(
3058 "org.freedesktop.systemd1",
3059 "/org/freedesktop/systemd1",
3060 "org.freedesktop.systemd1.Manager",
3065 return log_error_errno(r
, "Failed to enable subscription: %s", bus_error_message(&error
, r
));
3066 r
= sd_event_default(&wait_context
.event
);
3068 return log_error_errno(r
, "Failed to allocate event loop: %m");
3069 r
= sd_bus_attach_event(bus
, wait_context
.event
, 0);
3071 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
3074 STRV_FOREACH(name
, names
) {
3075 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3078 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
, arg_wait
? &wait_context
: NULL
);
3079 if (r
>= 0 && q
< 0)
3080 r
= translate_bus_error_to_exit_status(q
, &error
);
3083 if (!arg_no_block
) {
3084 int q
, arg_count
= 0;
3085 const char* extra_args
[4] = {};
3087 if (arg_scope
!= UNIT_FILE_SYSTEM
)
3088 extra_args
[arg_count
++] = "--user";
3090 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
3091 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
3092 extra_args
[arg_count
++] = "-H";
3093 extra_args
[arg_count
++] = arg_host
;
3094 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
3095 extra_args
[arg_count
++] = "-M";
3096 extra_args
[arg_count
++] = arg_host
;
3099 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
3103 /* When stopping units, warn if they can still be triggered by
3104 * another active unit (socket, path, timer) */
3105 if (!arg_quiet
&& streq(method
, "StopUnit"))
3106 STRV_FOREACH(name
, names
)
3107 check_triggering_units(bus
, *name
);
3110 if (r
>= 0 && arg_wait
) {
3112 q
= sd_event_loop(wait_context
.event
);
3114 return log_error_errno(q
, "Failed to run event loop: %m");
3115 if (wait_context
.any_failed
)
3122 static int logind_set_wall_message(void) {
3124 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3126 _cleanup_free_
char *m
= NULL
;
3129 r
= acquire_bus(BUS_FULL
, &bus
);
3133 m
= strv_join(arg_wall
, " ");
3137 r
= sd_bus_call_method(
3139 "org.freedesktop.login1",
3140 "/org/freedesktop/login1",
3141 "org.freedesktop.login1.Manager",
3150 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
3156 /* Ask systemd-logind, which might grant access to unprivileged users
3157 * through PolicyKit */
3158 static int logind_reboot(enum action a
) {
3160 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3161 const char *method
, *description
;
3165 r
= acquire_bus(BUS_FULL
, &bus
);
3173 description
= "reboot system";
3176 case ACTION_POWEROFF
:
3177 method
= "PowerOff";
3178 description
= "power off system";
3181 case ACTION_SUSPEND
:
3183 description
= "suspend system";
3186 case ACTION_HIBERNATE
:
3187 method
= "Hibernate";
3188 description
= "hibernate system";
3191 case ACTION_HYBRID_SLEEP
:
3192 method
= "HybridSleep";
3193 description
= "put system into hybrid sleep";
3200 polkit_agent_open_if_enabled();
3201 (void) logind_set_wall_message();
3203 r
= sd_bus_call_method(
3205 "org.freedesktop.login1",
3206 "/org/freedesktop/login1",
3207 "org.freedesktop.login1.Manager",
3211 "b", arg_ask_password
);
3213 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
3221 static int logind_check_inhibitors(enum action a
) {
3223 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3224 _cleanup_strv_free_
char **sessions
= NULL
;
3225 const char *what
, *who
, *why
, *mode
;
3232 if (arg_ignore_inhibitors
|| arg_force
> 0)
3244 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
3247 r
= acquire_bus(BUS_FULL
, &bus
);
3251 r
= sd_bus_call_method(
3253 "org.freedesktop.login1",
3254 "/org/freedesktop/login1",
3255 "org.freedesktop.login1.Manager",
3261 /* If logind is not around, then there are no inhibitors... */
3264 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3266 return bus_log_parse_error(r
);
3268 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3269 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3270 _cleanup_strv_free_
char **sv
= NULL
;
3272 if (!streq(mode
, "block"))
3275 sv
= strv_split(what
, ":");
3279 if ((pid_t
) pid
< 0)
3280 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
3282 if (!strv_contains(sv
,
3287 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3290 get_process_comm(pid
, &comm
);
3291 user
= uid_to_name(uid
);
3293 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3294 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3299 return bus_log_parse_error(r
);
3301 r
= sd_bus_message_exit_container(reply
);
3303 return bus_log_parse_error(r
);
3305 /* Check for current sessions */
3306 sd_get_sessions(&sessions
);
3307 STRV_FOREACH(s
, sessions
) {
3308 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3310 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3313 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3316 if (sd_session_get_type(*s
, &type
) < 0 || !STR_IN_SET(type
, "x11", "tty"))
3319 sd_session_get_tty(*s
, &tty
);
3320 sd_session_get_seat(*s
, &seat
);
3321 sd_session_get_service(*s
, &service
);
3322 user
= uid_to_name(uid
);
3324 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3331 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3332 action_table
[a
].verb
);
3340 static int logind_prepare_firmware_setup(void) {
3342 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3346 r
= acquire_bus(BUS_FULL
, &bus
);
3350 r
= sd_bus_call_method(
3352 "org.freedesktop.login1",
3353 "/org/freedesktop/login1",
3354 "org.freedesktop.login1.Manager",
3355 "SetRebootToFirmwareSetup",
3360 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3364 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3369 static int prepare_firmware_setup(void) {
3372 if (!arg_firmware_setup
)
3375 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3377 r
= efi_set_reboot_to_firmware(true);
3379 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3384 return logind_prepare_firmware_setup();
3387 static int set_exit_code(uint8_t code
) {
3388 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3392 r
= acquire_bus(BUS_MANAGER
, &bus
);
3396 r
= sd_bus_call_method(
3398 "org.freedesktop.systemd1",
3399 "/org/freedesktop/systemd1",
3400 "org.freedesktop.systemd1.Manager",
3406 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3411 static int start_special(int argc
, char *argv
[], void *userdata
) {
3417 a
= verb_to_action(argv
[0]);
3419 r
= logind_check_inhibitors(a
);
3423 if (arg_force
>= 2 && geteuid() != 0) {
3424 log_error("Must be root.");
3428 r
= prepare_firmware_setup();
3432 if (a
== ACTION_REBOOT
&& argc
> 1) {
3433 r
= update_reboot_parameter_and_warn(argv
[1]);
3437 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3440 /* If the exit code is not given on the command line,
3441 * don't reset it to zero: just keep it as it might
3442 * have been set previously. */
3444 r
= safe_atou8(argv
[1], &code
);
3446 return log_error_errno(r
, "Invalid exit code.");
3448 r
= set_exit_code(code
);
3453 if (arg_force
>= 2 &&
3460 if (arg_force
>= 1 &&
3467 return trivial_method(argc
, argv
, userdata
);
3469 /* First try logind, to allow authentication with polkit */
3475 ACTION_HYBRID_SLEEP
)) {
3476 r
= logind_reboot(a
);
3479 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3480 /* requested operation is not supported or already in progress */
3483 /* On all other errors, try low-level operation */
3486 return start_unit(argc
, argv
, userdata
);
3489 static int start_system_special(int argc
, char *argv
[], void *userdata
) {
3490 /* Like start_special above, but raises an error when running in user mode */
3492 if (arg_scope
!= UNIT_FILE_SYSTEM
) {
3493 log_error("Bad action for %s mode.",
3494 arg_scope
== UNIT_FILE_GLOBAL
? "--global" : "--user");
3498 return start_special(argc
, argv
, userdata
);
3501 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3502 _cleanup_strv_free_
char **names
= NULL
;
3503 UnitActiveState active_state
;
3509 r
= acquire_bus(BUS_MANAGER
, &bus
);
3513 r
= expand_names(bus
, args
, NULL
, &names
);
3515 return log_error_errno(r
, "Failed to expand names: %m");
3517 STRV_FOREACH(name
, names
) {
3518 r
= get_state_one_unit(bus
, *name
, &active_state
);
3523 puts(unit_active_state_to_string(active_state
));
3525 for (i
= 0; i
< nb_states
; ++i
)
3526 if (good_states
[i
] == active_state
)
3530 /* use the given return code for the case that we won't find
3531 * any unit which matches the list */
3532 return found
? 0 : code
;
3535 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3536 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3537 /* According to LSB: 3, "program is not running" */
3538 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3541 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3542 const UnitActiveState states
[] = { UNIT_FAILED
};
3543 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3546 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3547 _cleanup_strv_free_
char **names
= NULL
;
3548 char *kill_who
= NULL
, **name
;
3552 r
= acquire_bus(BUS_MANAGER
, &bus
);
3556 polkit_agent_open_if_enabled();
3559 arg_kill_who
= "all";
3561 /* --fail was specified */
3562 if (streq(arg_job_mode
, "fail"))
3563 kill_who
= strjoina(arg_kill_who
, "-fail");
3565 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3567 return log_error_errno(r
, "Failed to expand names: %m");
3569 STRV_FOREACH(name
, names
) {
3570 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3572 q
= sd_bus_call_method(
3574 "org.freedesktop.systemd1",
3575 "/org/freedesktop/systemd1",
3576 "org.freedesktop.systemd1.Manager",
3580 "ssi", *name
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3582 log_error_errno(q
, "Failed to kill unit %s: %s", *name
, bus_error_message(&error
, q
));
3591 typedef struct ExecStatusInfo
{
3599 usec_t start_timestamp
;
3600 usec_t exit_timestamp
;
3605 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3608 static void exec_status_info_free(ExecStatusInfo
*i
) {
3617 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3618 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3621 int32_t code
, status
;
3627 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3629 return bus_log_parse_error(r
);
3633 r
= sd_bus_message_read(m
, "s", &path
);
3635 return bus_log_parse_error(r
);
3637 i
->path
= strdup(path
);
3641 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3643 return bus_log_parse_error(r
);
3645 r
= sd_bus_message_read(m
,
3648 &start_timestamp
, &start_timestamp_monotonic
,
3649 &exit_timestamp
, &exit_timestamp_monotonic
,
3653 return bus_log_parse_error(r
);
3656 i
->start_timestamp
= (usec_t
) start_timestamp
;
3657 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3658 i
->pid
= (pid_t
) pid
;
3662 r
= sd_bus_message_exit_container(m
);
3664 return bus_log_parse_error(r
);
3669 typedef struct UnitCondition
{
3676 LIST_FIELDS(struct UnitCondition
, conditions
);
3679 static void unit_condition_free(UnitCondition
*c
) {
3688 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition
*, unit_condition_free
);
3690 typedef struct UnitStatusInfo
{
3692 const char *load_state
;
3693 const char *active_state
;
3694 const char *sub_state
;
3695 const char *unit_file_state
;
3696 const char *unit_file_preset
;
3698 const char *description
;
3699 const char *following
;
3701 char **documentation
;
3703 const char *fragment_path
;
3704 const char *source_path
;
3705 const char *control_group
;
3707 char **dropin_paths
;
3709 const char *load_error
;
3712 usec_t inactive_exit_timestamp
;
3713 usec_t inactive_exit_timestamp_monotonic
;
3714 usec_t active_enter_timestamp
;
3715 usec_t active_exit_timestamp
;
3716 usec_t inactive_enter_timestamp
;
3718 bool need_daemon_reload
;
3724 const char *status_text
;
3725 const char *pid_file
;
3729 usec_t start_timestamp
;
3730 usec_t exit_timestamp
;
3732 int exit_code
, exit_status
;
3734 usec_t condition_timestamp
;
3735 bool condition_result
;
3736 LIST_HEAD(UnitCondition
, conditions
);
3738 usec_t assert_timestamp
;
3740 bool failed_assert_trigger
;
3741 bool failed_assert_negate
;
3742 const char *failed_assert
;
3743 const char *failed_assert_parameter
;
3746 unsigned n_accepted
;
3747 unsigned n_connections
;
3750 /* Pairs of type, path */
3754 const char *sysfs_path
;
3756 /* Mount, Automount */
3763 uint64_t memory_current
;
3764 uint64_t memory_low
;
3765 uint64_t memory_high
;
3766 uint64_t memory_max
;
3767 uint64_t memory_swap_max
;
3768 uint64_t memory_limit
;
3769 uint64_t cpu_usage_nsec
;
3770 uint64_t tasks_current
;
3773 LIST_HEAD(ExecStatusInfo
, exec
);
3776 static void unit_status_info_free(UnitStatusInfo
*info
) {
3780 strv_free(info
->documentation
);
3781 strv_free(info
->dropin_paths
);
3782 strv_free(info
->listen
);
3784 while ((c
= info
->conditions
)) {
3785 LIST_REMOVE(conditions
, info
->conditions
, c
);
3786 unit_condition_free(c
);
3789 while ((p
= info
->exec
)) {
3790 LIST_REMOVE(exec
, info
->exec
, p
);
3791 exec_status_info_free(p
);
3795 static void print_status_info(
3801 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3803 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3804 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3811 /* This shows pretty information about a unit. See
3812 * print_property() for a low-level property printer */
3814 if (streq_ptr(i
->active_state
, "failed")) {
3815 active_on
= ansi_highlight_red();
3816 active_off
= ansi_normal();
3817 } else if (STRPTR_IN_SET(i
->active_state
, "active", "reloading")) {
3818 active_on
= ansi_highlight_green();
3819 active_off
= ansi_normal();
3821 active_on
= active_off
= "";
3823 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3825 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3826 printf(" - %s", i
->description
);
3831 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3833 if (streq_ptr(i
->load_state
, "error")) {
3834 on
= ansi_highlight_red();
3835 off
= ansi_normal();
3839 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3841 if (i
->load_error
!= 0)
3842 printf(" Loaded: %s%s%s (Reason: %s)\n",
3843 on
, strna(i
->load_state
), off
, i
->load_error
);
3844 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3845 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3846 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3847 else if (path
&& !isempty(i
->unit_file_state
))
3848 printf(" Loaded: %s%s%s (%s; %s)\n",
3849 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3851 printf(" Loaded: %s%s%s (%s)\n",
3852 on
, strna(i
->load_state
), off
, path
);
3854 printf(" Loaded: %s%s%s\n",
3855 on
, strna(i
->load_state
), off
);
3858 printf("Transient: yes\n");
3860 if (!strv_isempty(i
->dropin_paths
)) {
3861 _cleanup_free_
char *dir
= NULL
;
3865 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3866 if (! dir
|| last
) {
3867 printf(dir
? " " : " Drop-In: ");
3871 dir
= dirname_malloc(*dropin
);
3877 printf("%s\n %s", dir
,
3878 special_glyph(TREE_RIGHT
));
3881 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3883 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3887 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3889 printf(" Active: %s%s (%s)%s",
3890 active_on
, strna(i
->active_state
), ss
, active_off
);
3892 printf(" Active: %s%s%s",
3893 active_on
, strna(i
->active_state
), active_off
);
3895 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3896 printf(" (Result: %s)", i
->result
);
3898 timestamp
= STRPTR_IN_SET(i
->active_state
, "active", "reloading") ? i
->active_enter_timestamp
:
3899 STRPTR_IN_SET(i
->active_state
, "inactive", "failed") ? i
->inactive_enter_timestamp
:
3900 STRPTR_IN_SET(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3901 i
->active_exit_timestamp
;
3903 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3904 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3907 printf(" since %s; %s\n", s2
, s1
);
3909 printf(" since %s\n", s2
);
3913 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3917 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3918 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3920 printf("Condition: start %scondition failed%s at %s%s%s\n",
3921 ansi_highlight_yellow(), ansi_normal(),
3922 s2
, s1
? "; " : "", strempty(s1
));
3924 LIST_FOREACH(conditions
, c
, i
->conditions
)
3925 if (c
->tristate
< 0)
3928 LIST_FOREACH(conditions
, c
, i
->conditions
)
3929 if (c
->tristate
< 0)
3930 printf(" %s %s=%s%s%s was not met\n",
3931 --n
? special_glyph(TREE_BRANCH
) : special_glyph(TREE_RIGHT
),
3933 c
->trigger
? "|" : "",
3934 c
->negate
? "!" : "",
3938 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3939 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3940 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3942 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3943 ansi_highlight_red(), ansi_normal(),
3944 s2
, s1
? "; " : "", strempty(s1
));
3945 if (i
->failed_assert_trigger
)
3946 printf(" none of the trigger assertions were met\n");
3947 else if (i
->failed_assert
)
3948 printf(" %s=%s%s was not met\n",
3950 i
->failed_assert_negate
? "!" : "",
3951 i
->failed_assert_parameter
);
3955 printf(" Device: %s\n", i
->sysfs_path
);
3957 printf(" Where: %s\n", i
->where
);
3959 printf(" What: %s\n", i
->what
);
3961 STRV_FOREACH(t
, i
->documentation
)
3962 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3964 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3965 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3968 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3970 LIST_FOREACH(exec
, p
, i
->exec
) {
3971 _cleanup_free_
char *argv
= NULL
;
3974 /* Only show exited processes here */
3978 argv
= strv_join(p
->argv
, " ");
3979 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3981 good
= is_clean_exit(p
->code
, p
->status
, EXIT_CLEAN_DAEMON
, NULL
);
3983 on
= ansi_highlight_red();
3984 off
= ansi_normal();
3988 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3990 if (p
->code
== CLD_EXITED
) {
3993 printf("status=%i", p
->status
);
3995 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
4000 printf("signal=%s", signal_to_string(p
->status
));
4002 printf(")%s\n", off
);
4004 if (i
->main_pid
== p
->pid
&&
4005 i
->start_timestamp
== p
->start_timestamp
&&
4006 i
->exit_timestamp
== p
->start_timestamp
)
4007 /* Let's not show this twice */
4010 if (p
->pid
== i
->control_pid
)
4014 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
4015 if (i
->main_pid
> 0) {
4016 printf(" Main PID: "PID_FMT
, i
->main_pid
);
4019 _cleanup_free_
char *comm
= NULL
;
4020 (void) get_process_comm(i
->main_pid
, &comm
);
4022 printf(" (%s)", comm
);
4023 } else if (i
->exit_code
> 0) {
4024 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
4026 if (i
->exit_code
== CLD_EXITED
) {
4029 printf("status=%i", i
->exit_status
);
4031 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
4036 printf("signal=%s", signal_to_string(i
->exit_status
));
4041 if (i
->control_pid
> 0) {
4042 _cleanup_free_
char *c
= NULL
;
4044 if (i
->main_pid
> 0)
4045 fputs("; Control PID: ", stdout
);
4047 fputs("Cntrl PID: ", stdout
); /* if first in column, abbreviated so it fits alignment */
4049 printf(PID_FMT
, i
->control_pid
);
4051 (void) get_process_comm(i
->control_pid
, &c
);
4060 printf(" Status: \"%s\"\n", i
->status_text
);
4061 if (i
->status_errno
> 0)
4062 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
4064 if (i
->tasks_current
!= (uint64_t) -1) {
4065 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
4067 if (i
->tasks_max
!= (uint64_t) -1)
4068 printf(" (limit: %" PRIu64
")\n", i
->tasks_max
);
4073 if (i
->memory_current
!= (uint64_t) -1) {
4074 char buf
[FORMAT_BYTES_MAX
];
4076 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
4078 if (i
->memory_low
> 0 || i
->memory_high
!= CGROUP_LIMIT_MAX
||
4079 i
->memory_max
!= CGROUP_LIMIT_MAX
|| i
->memory_swap_max
!= CGROUP_LIMIT_MAX
||
4080 i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4081 const char *prefix
= "";
4084 if (i
->memory_low
> 0) {
4085 printf("%slow: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_low
));
4088 if (i
->memory_high
!= CGROUP_LIMIT_MAX
) {
4089 printf("%shigh: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_high
));
4092 if (i
->memory_max
!= CGROUP_LIMIT_MAX
) {
4093 printf("%smax: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_max
));
4096 if (i
->memory_swap_max
!= CGROUP_LIMIT_MAX
) {
4097 printf("%sswap max: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_swap_max
));
4100 if (i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4101 printf("%slimit: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
4109 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
4110 char buf
[FORMAT_TIMESPAN_MAX
];
4111 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
4114 if (i
->control_group
) {
4115 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4116 static const char prefix
[] = " ";
4119 printf(" CGroup: %s\n", i
->control_group
);
4122 if (c
> sizeof(prefix
) - 1)
4123 c
-= sizeof(prefix
) - 1;
4127 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
4132 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4134 if (i
->main_pid
> 0)
4135 extra
[k
++] = i
->main_pid
;
4137 if (i
->control_pid
> 0)
4138 extra
[k
++] = i
->control_pid
;
4140 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
4142 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
4145 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
4146 show_journal_by_unit(
4151 i
->inactive_exit_timestamp_monotonic
,
4154 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
4155 SD_JOURNAL_LOCAL_ONLY
,
4156 arg_scope
== UNIT_FILE_SYSTEM
,
4159 if (i
->need_daemon_reload
)
4160 warn_unit_file_changed(i
->id
);
4163 static void show_unit_help(UnitStatusInfo
*i
) {
4168 if (!i
->documentation
) {
4169 log_info("Documentation for %s not known.", i
->id
);
4173 STRV_FOREACH(p
, i
->documentation
)
4174 if (startswith(*p
, "man:"))
4175 show_man_page(*p
+ 4, false);
4177 log_info("Can't show: %s", *p
);
4180 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
4187 switch (contents
[0]) {
4189 case SD_BUS_TYPE_STRING
: {
4192 r
= sd_bus_message_read(m
, "s", &s
);
4194 return bus_log_parse_error(r
);
4197 if (streq(name
, "Id"))
4199 else if (streq(name
, "LoadState"))
4201 else if (streq(name
, "ActiveState"))
4202 i
->active_state
= s
;
4203 else if (streq(name
, "SubState"))
4205 else if (streq(name
, "Description"))
4207 else if (streq(name
, "FragmentPath"))
4208 i
->fragment_path
= s
;
4209 else if (streq(name
, "SourcePath"))
4212 else if (streq(name
, "DefaultControlGroup")) {
4214 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
4216 i
->control_group
= e
;
4219 else if (streq(name
, "ControlGroup"))
4220 i
->control_group
= s
;
4221 else if (streq(name
, "StatusText"))
4223 else if (streq(name
, "PIDFile"))
4225 else if (streq(name
, "SysFSPath"))
4227 else if (streq(name
, "Where"))
4229 else if (streq(name
, "What"))
4231 else if (streq(name
, "Following"))
4233 else if (streq(name
, "UnitFileState"))
4234 i
->unit_file_state
= s
;
4235 else if (streq(name
, "UnitFilePreset"))
4236 i
->unit_file_preset
= s
;
4237 else if (streq(name
, "Result"))
4244 case SD_BUS_TYPE_BOOLEAN
: {
4247 r
= sd_bus_message_read(m
, "b", &b
);
4249 return bus_log_parse_error(r
);
4251 if (streq(name
, "Accept"))
4253 else if (streq(name
, "NeedDaemonReload"))
4254 i
->need_daemon_reload
= b
;
4255 else if (streq(name
, "ConditionResult"))
4256 i
->condition_result
= b
;
4257 else if (streq(name
, "AssertResult"))
4258 i
->assert_result
= b
;
4259 else if (streq(name
, "Transient"))
4265 case SD_BUS_TYPE_UINT32
: {
4268 r
= sd_bus_message_read(m
, "u", &u
);
4270 return bus_log_parse_error(r
);
4272 if (streq(name
, "MainPID")) {
4274 i
->main_pid
= (pid_t
) u
;
4277 } else if (streq(name
, "ControlPID"))
4278 i
->control_pid
= (pid_t
) u
;
4279 else if (streq(name
, "ExecMainPID")) {
4281 i
->main_pid
= (pid_t
) u
;
4282 } else if (streq(name
, "NAccepted"))
4284 else if (streq(name
, "NConnections"))
4285 i
->n_connections
= u
;
4290 case SD_BUS_TYPE_INT32
: {
4293 r
= sd_bus_message_read(m
, "i", &j
);
4295 return bus_log_parse_error(r
);
4297 if (streq(name
, "ExecMainCode"))
4298 i
->exit_code
= (int) j
;
4299 else if (streq(name
, "ExecMainStatus"))
4300 i
->exit_status
= (int) j
;
4301 else if (streq(name
, "StatusErrno"))
4302 i
->status_errno
= (int) j
;
4307 case SD_BUS_TYPE_UINT64
: {
4310 r
= sd_bus_message_read(m
, "t", &u
);
4312 return bus_log_parse_error(r
);
4314 if (streq(name
, "ExecMainStartTimestamp"))
4315 i
->start_timestamp
= (usec_t
) u
;
4316 else if (streq(name
, "ExecMainExitTimestamp"))
4317 i
->exit_timestamp
= (usec_t
) u
;
4318 else if (streq(name
, "ActiveEnterTimestamp"))
4319 i
->active_enter_timestamp
= (usec_t
) u
;
4320 else if (streq(name
, "InactiveEnterTimestamp"))
4321 i
->inactive_enter_timestamp
= (usec_t
) u
;
4322 else if (streq(name
, "InactiveExitTimestamp"))
4323 i
->inactive_exit_timestamp
= (usec_t
) u
;
4324 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4325 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4326 else if (streq(name
, "ActiveExitTimestamp"))
4327 i
->active_exit_timestamp
= (usec_t
) u
;
4328 else if (streq(name
, "ConditionTimestamp"))
4329 i
->condition_timestamp
= (usec_t
) u
;
4330 else if (streq(name
, "AssertTimestamp"))
4331 i
->assert_timestamp
= (usec_t
) u
;
4332 else if (streq(name
, "MemoryCurrent"))
4333 i
->memory_current
= u
;
4334 else if (streq(name
, "MemoryLow"))
4336 else if (streq(name
, "MemoryHigh"))
4338 else if (streq(name
, "MemoryMax"))
4340 else if (streq(name
, "MemorySwapMax"))
4341 i
->memory_swap_max
= u
;
4342 else if (streq(name
, "MemoryLimit"))
4343 i
->memory_limit
= u
;
4344 else if (streq(name
, "TasksCurrent"))
4345 i
->tasks_current
= u
;
4346 else if (streq(name
, "TasksMax"))
4348 else if (streq(name
, "CPUUsageNSec"))
4349 i
->cpu_usage_nsec
= u
;
4354 case SD_BUS_TYPE_ARRAY
:
4356 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4357 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4359 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4361 return bus_log_parse_error(r
);
4363 info
= new0(ExecStatusInfo
, 1);
4367 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4369 info
->name
= strdup(name
);
4373 LIST_PREPEND(exec
, i
->exec
, info
);
4375 info
= new0(ExecStatusInfo
, 1);
4381 return bus_log_parse_error(r
);
4383 r
= sd_bus_message_exit_container(m
);
4385 return bus_log_parse_error(r
);
4389 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4390 const char *type
, *path
;
4392 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4394 return bus_log_parse_error(r
);
4396 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4398 r
= strv_extend(&i
->listen
, type
);
4402 r
= strv_extend(&i
->listen
, path
);
4407 return bus_log_parse_error(r
);
4409 r
= sd_bus_message_exit_container(m
);
4411 return bus_log_parse_error(r
);
4415 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4417 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4419 return bus_log_parse_error(r
);
4421 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4423 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4425 return bus_log_parse_error(r
);
4427 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4428 const char *cond
, *param
;
4429 int trigger
, negate
;
4432 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4434 return bus_log_parse_error(r
);
4436 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4437 _cleanup_(unit_condition_freep
) UnitCondition
*c
= NULL
;
4439 log_debug("%s trigger=%d negate=%d %s →%d", cond
, trigger
, negate
, param
, state
);
4441 c
= new0(UnitCondition
, 1);
4445 c
->name
= strdup(cond
);
4446 c
->param
= strdup(param
);
4447 if (!c
->name
|| !c
->param
)
4450 c
->trigger
= trigger
;
4452 c
->tristate
= state
;
4454 LIST_PREPEND(conditions
, i
->conditions
, c
);
4458 return bus_log_parse_error(r
);
4460 r
= sd_bus_message_exit_container(m
);
4462 return bus_log_parse_error(r
);
4464 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4465 const char *cond
, *param
;
4466 int trigger
, negate
;
4469 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4471 return bus_log_parse_error(r
);
4473 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4474 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4475 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4476 i
->failed_assert
= cond
;
4477 i
->failed_assert_trigger
= trigger
;
4478 i
->failed_assert_negate
= negate
;
4479 i
->failed_assert_parameter
= param
;
4483 return bus_log_parse_error(r
);
4485 r
= sd_bus_message_exit_container(m
);
4487 return bus_log_parse_error(r
);
4494 case SD_BUS_TYPE_STRUCT_BEGIN
:
4496 if (streq(name
, "LoadError")) {
4497 const char *n
, *message
;
4499 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4501 return bus_log_parse_error(r
);
4503 if (!isempty(message
))
4504 i
->load_error
= message
;
4517 r
= sd_bus_message_skip(m
, contents
);
4519 return bus_log_parse_error(r
);
4524 #define print_prop(name, fmt, ...) \
4527 printf(fmt "\n", __VA_ARGS__); \
4529 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4532 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4538 /* This is a low-level property printer, see
4539 * print_status_info() for the nicer output */
4541 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4542 /* skip what we didn't read */
4543 r
= sd_bus_message_skip(m
, contents
);
4547 switch (contents
[0]) {
4549 case SD_BUS_TYPE_STRUCT_BEGIN
:
4551 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4554 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4556 return bus_log_parse_error(r
);
4559 print_prop(name
, "%"PRIu32
, u
);
4561 print_prop(name
, "%s", "");
4565 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4568 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4570 return bus_log_parse_error(r
);
4572 if (arg_all
|| !isempty(s
))
4573 print_prop(name
, "%s", s
);
4577 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4578 const char *a
= NULL
, *b
= NULL
;
4580 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4582 return bus_log_parse_error(r
);
4584 if (arg_all
|| !isempty(a
) || !isempty(b
))
4585 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4588 } else if (streq_ptr(name
, "SystemCallFilter")) {
4589 _cleanup_strv_free_
char **l
= NULL
;
4592 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4594 return bus_log_parse_error(r
);
4596 r
= sd_bus_message_read(m
, "b", &whitelist
);
4598 return bus_log_parse_error(r
);
4600 r
= sd_bus_message_read_strv(m
, &l
);
4602 return bus_log_parse_error(r
);
4604 r
= sd_bus_message_exit_container(m
);
4606 return bus_log_parse_error(r
);
4608 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4613 fputs(name
, stdout
);
4620 STRV_FOREACH(i
, l
) {
4628 fputc('\n', stdout
);
4636 case SD_BUS_TYPE_ARRAY
:
4638 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4642 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4644 return bus_log_parse_error(r
);
4646 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4647 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path
, yes_no(ignore
));
4650 return bus_log_parse_error(r
);
4652 r
= sd_bus_message_exit_container(m
);
4654 return bus_log_parse_error(r
);
4658 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4659 const char *type
, *path
;
4661 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4663 return bus_log_parse_error(r
);
4665 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4666 print_prop(type
, "%s", path
);
4668 return bus_log_parse_error(r
);
4670 r
= sd_bus_message_exit_container(m
);
4672 return bus_log_parse_error(r
);
4676 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4677 const char *type
, *path
;
4679 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4681 return bus_log_parse_error(r
);
4683 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4687 printf("Listen%s=%s\n", type
, path
);
4689 return bus_log_parse_error(r
);
4691 r
= sd_bus_message_exit_container(m
);
4693 return bus_log_parse_error(r
);
4697 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4699 uint64_t value
, next_elapse
;
4701 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4703 return bus_log_parse_error(r
);
4705 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4706 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4708 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4709 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4710 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4713 return bus_log_parse_error(r
);
4715 r
= sd_bus_message_exit_container(m
);
4717 return bus_log_parse_error(r
);
4721 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4722 ExecStatusInfo info
= {};
4724 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4726 return bus_log_parse_error(r
);
4728 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4729 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4730 _cleanup_free_
char *tt
;
4732 tt
= strv_join(info
.argv
, " ");
4735 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4738 yes_no(info
.ignore
),
4739 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4740 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4742 sigchld_code_to_string(info
.code
),
4744 info
.code
== CLD_EXITED
? "" : "/",
4745 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4748 strv_free(info
.argv
);
4752 r
= sd_bus_message_exit_container(m
);
4754 return bus_log_parse_error(r
);
4758 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4759 const char *path
, *rwm
;
4761 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4763 return bus_log_parse_error(r
);
4765 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4766 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4768 return bus_log_parse_error(r
);
4770 r
= sd_bus_message_exit_container(m
);
4772 return bus_log_parse_error(r
);
4776 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4777 STR_IN_SET(name
, "IODeviceWeight", "BlockIODeviceWeight")) {
4781 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4783 return bus_log_parse_error(r
);
4785 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4786 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4788 return bus_log_parse_error(r
);
4790 r
= sd_bus_message_exit_container(m
);
4792 return bus_log_parse_error(r
);
4796 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4797 (cgroup_io_limit_type_from_string(name
) >= 0 ||
4798 STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
4802 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4804 return bus_log_parse_error(r
);
4806 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4807 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4809 return bus_log_parse_error(r
);
4811 r
= sd_bus_message_exit_container(m
);
4813 return bus_log_parse_error(r
);
4821 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4823 return bus_log_parse_error(r
);
4826 r
= sd_bus_message_skip(m
, contents
);
4828 return bus_log_parse_error(r
);
4831 printf("%s=[unprintable]\n", name
);
4837 static int show_one(
4842 bool show_properties
,
4846 static const struct bus_properties_map property_map
[] = {
4847 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
4848 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
) },
4852 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4853 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4854 _cleanup_set_free_ Set
*found_properties
= NULL
;
4855 _cleanup_(unit_status_info_free
) UnitStatusInfo info
= {
4856 .memory_current
= (uint64_t) -1,
4857 .memory_high
= CGROUP_LIMIT_MAX
,
4858 .memory_max
= CGROUP_LIMIT_MAX
,
4859 .memory_swap_max
= CGROUP_LIMIT_MAX
,
4860 .memory_limit
= (uint64_t) -1,
4861 .cpu_usage_nsec
= (uint64_t) -1,
4862 .tasks_current
= (uint64_t) -1,
4863 .tasks_max
= (uint64_t) -1,
4870 log_debug("Showing one %s", path
);
4872 r
= sd_bus_call_method(
4874 "org.freedesktop.systemd1",
4876 "org.freedesktop.DBus.Properties",
4882 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4885 r
= bus_message_map_all_properties(reply
, property_map
, &info
);
4887 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
4889 if (streq_ptr(info
.load_state
, "not-found") && streq_ptr(info
.active_state
, "inactive")) {
4890 log_full(streq(verb
, "status") ? LOG_ERR
: LOG_DEBUG
,
4891 "Unit %s could not be found.", unit
);
4893 if (streq(verb
, "status"))
4894 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
;
4896 if (!streq(verb
, "show"))
4900 r
= sd_bus_message_rewind(reply
, true);
4902 return log_error_errno(r
, "Failed to rewind: %s", bus_error_message(&error
, r
));
4905 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4907 return bus_log_parse_error(r
);
4914 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4915 const char *name
, *contents
;
4917 r
= sd_bus_message_read(reply
, "s", &name
);
4919 return bus_log_parse_error(r
);
4921 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4923 return bus_log_parse_error(r
);
4925 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4927 return bus_log_parse_error(r
);
4929 if (show_properties
) {
4930 r
= set_ensure_allocated(&found_properties
, &string_hash_ops
);
4934 r
= set_put(found_properties
, name
);
4935 if (r
< 0 && r
!= EEXIST
)
4938 r
= print_property(name
, reply
, contents
);
4940 r
= status_property(name
, reply
, &info
, contents
);
4944 r
= sd_bus_message_exit_container(reply
);
4946 return bus_log_parse_error(r
);
4948 r
= sd_bus_message_exit_container(reply
);
4950 return bus_log_parse_error(r
);
4953 return bus_log_parse_error(r
);
4955 r
= sd_bus_message_exit_container(reply
);
4957 return bus_log_parse_error(r
);
4960 if (show_properties
) {
4962 int not_found_level
= streq(verb
, "show") ? LOG_DEBUG
: LOG_WARNING
;
4964 STRV_FOREACH(pp
, arg_properties
)
4965 if (!set_contains(found_properties
, *pp
)) {
4966 log_full(not_found_level
, "Property %s does not exist.", *pp
);
4970 } else if (streq(verb
, "help"))
4971 show_unit_help(&info
);
4972 else if (streq(verb
, "status")) {
4973 print_status_info(bus
, &info
, ellipsized
);
4975 if (info
.active_state
&& !STR_IN_SET(info
.active_state
, "active", "reloading"))
4976 r
= EXIT_PROGRAM_NOT_RUNNING
;
4978 r
= EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
;
4984 static int get_unit_dbus_path_by_pid(
4989 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4990 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4994 r
= sd_bus_call_method(
4996 "org.freedesktop.systemd1",
4997 "/org/freedesktop/systemd1",
4998 "org.freedesktop.systemd1.Manager",
5004 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
5006 r
= sd_bus_message_read(reply
, "o", &u
);
5008 return bus_log_parse_error(r
);
5018 static int show_all(
5021 bool show_properties
,
5025 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5026 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
5031 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
5035 pager_open(arg_no_pager
, false);
5039 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
5041 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
5042 _cleanup_free_
char *p
= NULL
;
5044 p
= unit_dbus_path_from_name(u
->id
);
5048 r
= show_one(verb
, bus
, p
, u
->id
, show_properties
, new_line
, ellipsized
);
5051 else if (r
> 0 && ret
== 0)
5058 static int show_system_status(sd_bus
*bus
) {
5059 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
5060 _cleanup_free_
char *hn
= NULL
;
5061 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
5062 const char *on
, *off
;
5065 hn
= gethostname_malloc();
5069 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
5071 return log_error_errno(r
, "Failed to read server status: %m");
5073 if (streq_ptr(mi
.state
, "degraded")) {
5074 on
= ansi_highlight_red();
5075 off
= ansi_normal();
5076 } else if (!streq_ptr(mi
.state
, "running")) {
5077 on
= ansi_highlight_yellow();
5078 off
= ansi_normal();
5082 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
5084 printf(" State: %s%s%s\n",
5085 on
, strna(mi
.state
), off
);
5087 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
5088 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
5090 printf(" Since: %s; %s\n",
5091 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
5092 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
5094 printf(" CGroup: %s\n", mi
.control_group
?: "/");
5095 if (IN_SET(arg_transport
,
5096 BUS_TRANSPORT_LOCAL
,
5097 BUS_TRANSPORT_MACHINE
)) {
5098 static const char prefix
[] = " ";
5102 if (c
> sizeof(prefix
) - 1)
5103 c
-= sizeof(prefix
) - 1;
5107 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
5113 static int show(int argc
, char *argv
[], void *userdata
) {
5114 bool show_properties
, show_status
, show_help
, new_line
= false;
5115 bool ellipsized
= false;
5121 show_properties
= streq(argv
[0], "show");
5122 show_status
= streq(argv
[0], "status");
5123 show_help
= streq(argv
[0], "help");
5125 if (show_help
&& argc
<= 1) {
5126 log_error("This command expects one or more unit names. Did you mean --help?");
5130 r
= acquire_bus(BUS_MANAGER
, &bus
);
5134 pager_open(arg_no_pager
, false);
5137 /* Increase max number of open files to 16K if we can, we
5138 * might needs this when browsing journal files, which might
5139 * be split up into many files. */
5140 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
5142 /* If no argument is specified inspect the manager itself */
5143 if (show_properties
&& argc
<= 1)
5144 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", NULL
, show_properties
, &new_line
, &ellipsized
);
5146 if (show_status
&& argc
<= 1) {
5148 show_system_status(bus
);
5152 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
5154 _cleanup_free_
char **patterns
= NULL
;
5157 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
5158 _cleanup_free_
char *path
= NULL
, *unit
= NULL
;
5161 if (safe_atou32(*name
, &id
) < 0) {
5162 if (strv_push(&patterns
, *name
) < 0)
5166 } else if (show_properties
) {
5167 /* Interpret as job id */
5168 if (asprintf(&path
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
5172 /* Interpret as PID */
5173 r
= get_unit_dbus_path_by_pid(bus
, id
, &path
);
5179 r
= unit_name_from_dbus_path(path
, &unit
);
5184 r
= show_one(argv
[0], bus
, path
, unit
, show_properties
, &new_line
, &ellipsized
);
5187 else if (r
> 0 && ret
== 0)
5191 if (!strv_isempty(patterns
)) {
5192 _cleanup_strv_free_
char **names
= NULL
;
5194 r
= expand_names(bus
, patterns
, NULL
, &names
);
5196 return log_error_errno(r
, "Failed to expand names: %m");
5198 STRV_FOREACH(name
, names
) {
5199 _cleanup_free_
char *path
;
5201 path
= unit_dbus_path_from_name(*name
);
5205 r
= show_one(argv
[0], bus
, path
, *name
, show_properties
, &new_line
, &ellipsized
);
5208 if (r
> 0 && ret
== 0)
5214 if (ellipsized
&& !arg_quiet
)
5215 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5220 static int cat_file(const char *filename
, bool newline
) {
5221 _cleanup_close_
int fd
;
5223 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
5227 printf("%s%s# %s%s\n",
5228 newline
? "\n" : "",
5229 ansi_highlight_blue(),
5234 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
5237 static int cat(int argc
, char *argv
[], void *userdata
) {
5238 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5239 _cleanup_strv_free_
char **names
= NULL
;
5245 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5246 log_error("Cannot remotely cat units.");
5250 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
5252 return log_error_errno(r
, "Failed to determine unit paths: %m");
5254 r
= acquire_bus(BUS_MANAGER
, &bus
);
5258 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5260 return log_error_errno(r
, "Failed to expand names: %m");
5262 pager_open(arg_no_pager
, false);
5264 STRV_FOREACH(name
, names
) {
5265 _cleanup_free_
char *fragment_path
= NULL
;
5266 _cleanup_strv_free_
char **dropin_paths
= NULL
;
5269 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
5280 if (need_daemon_reload(bus
, *name
) > 0) /* ignore errors (<0), this is informational output */
5282 "%s# Warning: %s changed on disk, the version systemd has loaded is outdated.\n"
5283 "%s# This output shows the current version of the unit's original fragment and drop-in files.\n"
5284 "%s# If fragments or drop-ins were added or removed, they are not properly reflected in this output.\n"
5285 "%s# Run 'systemctl%s daemon-reload' to reload units.%s\n",
5286 ansi_highlight_red(),
5288 ansi_highlight_red(),
5289 ansi_highlight_red(),
5290 ansi_highlight_red(),
5291 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
5294 if (fragment_path
) {
5295 r
= cat_file(fragment_path
, false);
5297 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
5300 STRV_FOREACH(path
, dropin_paths
) {
5301 r
= cat_file(*path
, path
== dropin_paths
);
5303 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
5310 static int set_property(int argc
, char *argv
[], void *userdata
) {
5311 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5312 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5313 _cleanup_free_
char *n
= NULL
;
5317 r
= acquire_bus(BUS_MANAGER
, &bus
);
5321 polkit_agent_open_if_enabled();
5323 r
= sd_bus_message_new_method_call(
5326 "org.freedesktop.systemd1",
5327 "/org/freedesktop/systemd1",
5328 "org.freedesktop.systemd1.Manager",
5329 "SetUnitProperties");
5331 return bus_log_create_error(r
);
5333 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
5335 return log_error_errno(r
, "Failed to mangle unit name: %m");
5337 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
5339 return bus_log_create_error(r
);
5341 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
5343 return bus_log_create_error(r
);
5345 r
= bus_append_unit_property_assignment_many(m
, strv_skip(argv
, 2));
5349 r
= sd_bus_message_close_container(m
);
5351 return bus_log_create_error(r
);
5353 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5355 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
5360 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5361 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5362 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5367 r
= acquire_bus(BUS_MANAGER
, &bus
);
5371 polkit_agent_open_if_enabled();
5373 switch (arg_action
) {
5380 method
= "Reexecute";
5383 case ACTION_SYSTEMCTL
:
5384 method
= streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5385 /* "daemon-reload" */ "Reload";
5389 assert_not_reached("Unexpected action");
5392 r
= sd_bus_message_new_method_call(
5395 "org.freedesktop.systemd1",
5396 "/org/freedesktop/systemd1",
5397 "org.freedesktop.systemd1.Manager",
5400 return bus_log_create_error(r
);
5402 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5403 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5404 * their timeout, and for everything else there's the same time budget in place. */
5406 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
5408 /* On reexecution, we expect a disconnect, not a reply */
5409 if (IN_SET(r
, -ETIMEDOUT
, -ECONNRESET
) && streq(method
, "Reexecute"))
5412 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5413 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5415 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5416 * old ways of doing things, hence don't log any error in that case here. */
5418 return r
< 0 ? r
: 0;
5421 static int trivial_method(int argc
, char *argv
[], void *userdata
) {
5422 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5427 r
= acquire_bus(BUS_MANAGER
, &bus
);
5431 polkit_agent_open_if_enabled();
5434 streq(argv
[0], "clear-jobs") ||
5435 streq(argv
[0], "cancel") ? "ClearJobs" :
5436 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5437 streq(argv
[0], "halt") ? "Halt" :
5438 streq(argv
[0], "reboot") ? "Reboot" :
5439 streq(argv
[0], "kexec") ? "KExec" :
5440 streq(argv
[0], "exit") ? "Exit" :
5441 /* poweroff */ "PowerOff";
5443 r
= sd_bus_call_method(
5445 "org.freedesktop.systemd1",
5446 "/org/freedesktop/systemd1",
5447 "org.freedesktop.systemd1.Manager",
5452 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5453 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5455 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5456 * old ways of doing things, hence don't log any error in that case here. */
5458 return r
< 0 ? r
: 0;
5461 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5462 _cleanup_strv_free_
char **names
= NULL
;
5468 return trivial_method(argc
, argv
, userdata
);
5470 r
= acquire_bus(BUS_MANAGER
, &bus
);
5474 polkit_agent_open_if_enabled();
5476 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5478 return log_error_errno(r
, "Failed to expand names: %m");
5480 STRV_FOREACH(name
, names
) {
5481 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5483 q
= sd_bus_call_method(
5485 "org.freedesktop.systemd1",
5486 "/org/freedesktop/systemd1",
5487 "org.freedesktop.systemd1.Manager",
5493 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5502 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5503 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5504 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5509 r
= acquire_bus(BUS_MANAGER
, &bus
);
5513 pager_open(arg_no_pager
, false);
5515 r
= sd_bus_get_property(
5517 "org.freedesktop.systemd1",
5518 "/org/freedesktop/systemd1",
5519 "org.freedesktop.systemd1.Manager",
5525 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5527 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5529 return bus_log_parse_error(r
);
5531 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5534 return bus_log_parse_error(r
);
5536 r
= sd_bus_message_exit_container(reply
);
5538 return bus_log_parse_error(r
);
5543 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5544 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5545 _cleanup_free_
char *cmdline_init
= NULL
;
5546 const char *root
, *init
;
5550 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5551 log_error("Cannot switch root remotely.");
5555 if (argc
< 2 || argc
> 3) {
5556 log_error("Wrong number of arguments.");
5565 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5566 "init", &cmdline_init
,
5569 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5571 init
= cmdline_init
;
5574 init
= empty_to_null(init
);
5576 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5578 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5579 root_init_path
= strjoina(root
, "/", init
);
5581 /* If the passed init is actually the same as the
5582 * systemd binary, then let's suppress it. */
5583 if (files_same(root_init_path
, root_systemd_path
) > 0)
5587 r
= acquire_bus(BUS_MANAGER
, &bus
);
5591 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5593 r
= sd_bus_call_method(
5595 "org.freedesktop.systemd1",
5596 "/org/freedesktop/systemd1",
5597 "org.freedesktop.systemd1.Manager",
5603 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5608 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5609 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5610 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5618 r
= acquire_bus(BUS_MANAGER
, &bus
);
5622 polkit_agent_open_if_enabled();
5624 method
= streq(argv
[0], "set-environment")
5626 : "UnsetEnvironment";
5628 r
= sd_bus_message_new_method_call(
5631 "org.freedesktop.systemd1",
5632 "/org/freedesktop/systemd1",
5633 "org.freedesktop.systemd1.Manager",
5636 return bus_log_create_error(r
);
5638 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5640 return bus_log_create_error(r
);
5642 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5644 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5649 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5650 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5651 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5655 r
= acquire_bus(BUS_MANAGER
, &bus
);
5659 polkit_agent_open_if_enabled();
5661 r
= sd_bus_message_new_method_call(
5664 "org.freedesktop.systemd1",
5665 "/org/freedesktop/systemd1",
5666 "org.freedesktop.systemd1.Manager",
5669 return bus_log_create_error(r
);
5672 r
= sd_bus_message_append_strv(m
, environ
);
5676 r
= sd_bus_message_open_container(m
, 'a', "s");
5678 return bus_log_create_error(r
);
5680 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5682 if (!env_name_is_valid(*a
)) {
5683 log_error("Not a valid environment variable name: %s", *a
);
5687 STRV_FOREACH(b
, environ
) {
5690 eq
= startswith(*b
, *a
);
5691 if (eq
&& *eq
== '=') {
5693 r
= sd_bus_message_append(m
, "s", *b
);
5695 return bus_log_create_error(r
);
5702 r
= sd_bus_message_close_container(m
);
5705 return bus_log_create_error(r
);
5707 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5709 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5714 static int enable_sysv_units(const char *verb
, char **args
) {
5717 #if defined(HAVE_SYSV_COMPAT)
5718 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5721 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5723 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5726 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5729 if (!STR_IN_SET(verb
,
5735 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5742 const char *argv
[] = {
5743 ROOTLIBEXECDIR
"/systemd-sysv-install",
5750 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5751 bool found_native
= false, found_sysv
;
5760 if (!endswith(name
, ".service"))
5763 if (path_is_absolute(name
))
5766 j
= unit_file_exists(arg_scope
, &paths
, name
);
5767 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5768 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5769 found_native
= j
!= 0;
5771 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5772 * prefer the native unit */
5773 if (found_native
&& streq(verb
, "is-enabled"))
5776 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5780 p
[strlen(p
) - strlen(".service")] = 0;
5781 found_sysv
= access(p
, F_OK
) >= 0;
5787 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5789 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5792 if (!isempty(arg_root
))
5793 argv
[c
++] = q
= strappend("--root=", arg_root
);
5796 argv
[c
++] = basename(p
);
5799 l
= strv_join((char**)argv
, " ");
5803 log_info("Executing: %s", l
);
5807 return log_error_errno(errno
, "Failed to fork: %m");
5808 else if (pid
== 0) {
5811 (void) reset_all_signal_handlers();
5812 (void) reset_signal_mask();
5814 execv(argv
[0], (char**) argv
);
5815 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
5816 _exit(EXIT_FAILURE
);
5819 j
= wait_for_terminate(pid
, &status
);
5821 return log_error_errno(j
, "Failed to wait for child: %m");
5823 if (status
.si_code
== CLD_EXITED
) {
5824 if (streq(verb
, "is-enabled")) {
5825 if (status
.si_status
== 0) {
5834 } else if (status
.si_status
!= 0)
5835 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
5837 log_error("Unexpected waitid() result.");
5844 /* Remove this entry, so that we don't try enabling it as native unit */
5847 assert(args
[f
] == name
);
5848 strv_remove(args
, name
);
5855 static int mangle_names(char **original_names
, char ***mangled_names
) {
5856 char **i
, **l
, **name
;
5859 l
= i
= new(char*, strv_length(original_names
) + 1);
5863 STRV_FOREACH(name
, original_names
) {
5865 /* When enabling units qualified path names are OK,
5866 * too, hence allow them explicitly. */
5868 if (is_path(*name
)) {
5875 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5878 return log_error_errno(r
, "Failed to mangle unit name: %m");
5891 static int normalize_names(char **names
, bool warn_if_path
) {
5893 bool was_path
= false;
5895 STRV_FOREACH(u
, names
) {
5901 r
= free_and_strdup(u
, basename(*u
));
5903 return log_error_errno(r
, "Failed to normalize unit file path: %m");
5908 if (warn_if_path
&& was_path
)
5909 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
5914 static int unit_exists(const char *unit
) {
5915 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5916 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5917 _cleanup_free_
char *path
= NULL
;
5918 static const struct bus_properties_map property_map
[] = {
5919 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
5920 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
)},
5923 UnitStatusInfo info
= {};
5927 path
= unit_dbus_path_from_name(unit
);
5931 r
= acquire_bus(BUS_MANAGER
, &bus
);
5935 r
= sd_bus_call_method(
5937 "org.freedesktop.systemd1",
5939 "org.freedesktop.DBus.Properties",
5945 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
5947 r
= bus_message_map_all_properties(reply
, property_map
, &info
);
5949 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
5951 return !streq_ptr(info
.load_state
, "not-found") || !streq_ptr(info
.active_state
, "inactive");
5954 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5955 _cleanup_strv_free_
char **names
= NULL
;
5956 const char *verb
= argv
[0];
5957 UnitFileChange
*changes
= NULL
;
5958 unsigned n_changes
= 0;
5959 int carries_install_info
= -1;
5960 bool ignore_carries_install_info
= arg_quiet
;
5966 r
= mangle_names(strv_skip(argv
, 1), &names
);
5970 r
= enable_sysv_units(verb
, names
);
5974 /* If the operation was fully executed by the SysV compat, let's finish early */
5975 if (strv_isempty(names
)) {
5976 if (arg_no_reload
|| install_client_side())
5978 return daemon_reload(argc
, argv
, userdata
);
5981 if (streq(verb
, "disable")) {
5982 r
= normalize_names(names
, true);
5987 if (install_client_side()) {
5988 UnitFileFlags flags
;
5990 flags
= args_to_flags();
5991 if (streq(verb
, "enable")) {
5992 r
= unit_file_enable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
5993 carries_install_info
= r
;
5994 } else if (streq(verb
, "disable"))
5995 r
= unit_file_disable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
5996 else if (streq(verb
, "reenable")) {
5997 r
= unit_file_reenable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
5998 carries_install_info
= r
;
5999 } else if (streq(verb
, "link"))
6000 r
= unit_file_link(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6001 else if (streq(verb
, "preset")) {
6002 r
= unit_file_preset(arg_scope
, flags
, arg_root
, names
, arg_preset_mode
, &changes
, &n_changes
);
6003 } else if (streq(verb
, "mask"))
6004 r
= unit_file_mask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6005 else if (streq(verb
, "unmask"))
6006 r
= unit_file_unmask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6007 else if (streq(verb
, "revert"))
6008 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
6010 assert_not_reached("Unknown verb");
6012 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
6017 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6018 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6019 bool expect_carries_install_info
= false;
6020 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
6024 if (STR_IN_SET(verb
, "mask", "unmask")) {
6025 r
= unit_exists(*names
);
6029 log_notice("Unit %s does not exist, proceeding anyway.", *names
);
6032 r
= acquire_bus(BUS_MANAGER
, &bus
);
6036 polkit_agent_open_if_enabled();
6038 if (streq(verb
, "enable")) {
6039 method
= "EnableUnitFiles";
6040 expect_carries_install_info
= true;
6041 } else if (streq(verb
, "disable")) {
6042 method
= "DisableUnitFiles";
6044 } else if (streq(verb
, "reenable")) {
6045 method
= "ReenableUnitFiles";
6046 expect_carries_install_info
= true;
6047 } else if (streq(verb
, "link"))
6048 method
= "LinkUnitFiles";
6049 else if (streq(verb
, "preset")) {
6051 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
6052 method
= "PresetUnitFilesWithMode";
6053 send_preset_mode
= true;
6055 method
= "PresetUnitFiles";
6057 expect_carries_install_info
= true;
6058 ignore_carries_install_info
= true;
6059 } else if (streq(verb
, "mask"))
6060 method
= "MaskUnitFiles";
6061 else if (streq(verb
, "unmask")) {
6062 method
= "UnmaskUnitFiles";
6064 } else if (streq(verb
, "revert")) {
6065 method
= "RevertUnitFiles";
6066 send_runtime
= send_force
= false;
6068 assert_not_reached("Unknown verb");
6070 r
= sd_bus_message_new_method_call(
6073 "org.freedesktop.systemd1",
6074 "/org/freedesktop/systemd1",
6075 "org.freedesktop.systemd1.Manager",
6078 return bus_log_create_error(r
);
6080 r
= sd_bus_message_append_strv(m
, names
);
6082 return bus_log_create_error(r
);
6084 if (send_preset_mode
) {
6085 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
6087 return bus_log_create_error(r
);
6091 r
= sd_bus_message_append(m
, "b", arg_runtime
);
6093 return bus_log_create_error(r
);
6097 r
= sd_bus_message_append(m
, "b", arg_force
);
6099 return bus_log_create_error(r
);
6102 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6104 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
6106 if (expect_carries_install_info
) {
6107 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
6109 return bus_log_parse_error(r
);
6112 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6116 /* Try to reload if enabled */
6118 r
= daemon_reload(argc
, argv
, userdata
);
6123 if (carries_install_info
== 0 && !ignore_carries_install_info
)
6124 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6125 "settings in the [Install] section, and DefaultInstance for template units).\n"
6126 "This means they are not meant to be enabled using systemctl.\n"
6127 "Possible reasons for having this kind of units are:\n"
6128 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6129 " .wants/ or .requires/ directory.\n"
6130 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6131 " a requirement dependency on it.\n"
6132 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6133 " D-Bus, udev, scripted systemctl call, ...).\n"
6134 "4) In case of template units, the unit is meant to be enabled with some\n"
6135 " instance name specified.");
6137 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
6138 char *new_args
[n_changes
+ 2];
6142 r
= acquire_bus(BUS_MANAGER
, &bus
);
6146 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
6147 for (i
= 0; i
< n_changes
; i
++)
6148 new_args
[i
+ 1] = basename(changes
[i
].path
);
6149 new_args
[i
+ 1] = NULL
;
6151 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
6155 unit_file_changes_free(changes
, n_changes
);
6160 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
6161 _cleanup_strv_free_
char **names
= NULL
;
6162 _cleanup_free_
char *target
= NULL
;
6163 const char *verb
= argv
[0];
6164 UnitFileChange
*changes
= NULL
;
6165 unsigned n_changes
= 0;
6172 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
6174 return log_error_errno(r
, "Failed to mangle unit name: %m");
6176 r
= mangle_names(strv_skip(argv
, 2), &names
);
6180 if (streq(verb
, "add-wants"))
6182 else if (streq(verb
, "add-requires"))
6183 dep
= UNIT_REQUIRES
;
6185 assert_not_reached("Unknown verb");
6187 if (install_client_side()) {
6188 r
= unit_file_add_dependency(arg_scope
, args_to_flags(), arg_root
, names
, target
, dep
, &changes
, &n_changes
);
6189 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
6194 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6195 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6198 r
= acquire_bus(BUS_MANAGER
, &bus
);
6202 polkit_agent_open_if_enabled();
6204 r
= sd_bus_message_new_method_call(
6207 "org.freedesktop.systemd1",
6208 "/org/freedesktop/systemd1",
6209 "org.freedesktop.systemd1.Manager",
6210 "AddDependencyUnitFiles");
6212 return bus_log_create_error(r
);
6214 r
= sd_bus_message_append_strv(m
, names
);
6216 return bus_log_create_error(r
);
6218 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
6220 return bus_log_create_error(r
);
6222 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6224 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
6226 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6230 if (arg_no_reload
) {
6235 r
= daemon_reload(argc
, argv
, userdata
);
6239 unit_file_changes_free(changes
, n_changes
);
6244 static int preset_all(int argc
, char *argv
[], void *userdata
) {
6245 UnitFileChange
*changes
= NULL
;
6246 unsigned n_changes
= 0;
6249 if (install_client_side()) {
6250 r
= unit_file_preset_all(arg_scope
, args_to_flags(), arg_root
, arg_preset_mode
, &changes
, &n_changes
);
6251 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
6256 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6257 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6260 r
= acquire_bus(BUS_MANAGER
, &bus
);
6264 polkit_agent_open_if_enabled();
6266 r
= sd_bus_call_method(
6268 "org.freedesktop.systemd1",
6269 "/org/freedesktop/systemd1",
6270 "org.freedesktop.systemd1.Manager",
6271 "PresetAllUnitFiles",
6275 unit_file_preset_mode_to_string(arg_preset_mode
),
6279 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
6281 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6285 if (arg_no_reload
) {
6290 r
= daemon_reload(argc
, argv
, userdata
);
6294 unit_file_changes_free(changes
, n_changes
);
6299 static int show_installation_targets_client_side(const char *name
) {
6300 UnitFileChange
*changes
= NULL
;
6301 unsigned n_changes
= 0, i
;
6302 UnitFileFlags flags
;
6306 p
= STRV_MAKE(name
);
6307 flags
= UNIT_FILE_DRY_RUN
|
6308 (arg_runtime
? UNIT_FILE_RUNTIME
: 0);
6310 r
= unit_file_disable(UNIT_FILE_SYSTEM
, flags
, NULL
, p
, &changes
, &n_changes
);
6312 return log_error_errno(r
, "Failed to get file links for %s: %m", name
);
6314 for (i
= 0; i
< n_changes
; i
++)
6315 if (changes
[i
].type
== UNIT_FILE_UNLINK
)
6316 printf(" %s\n", changes
[i
].path
);
6321 static int show_installation_targets(sd_bus
*bus
, const char *name
) {
6322 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6323 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6327 r
= sd_bus_call_method(
6329 "org.freedesktop.systemd1",
6330 "/org/freedesktop/systemd1",
6331 "org.freedesktop.systemd1.Manager",
6335 "sb", name
, arg_runtime
);
6337 return log_error_errno(r
, "Failed to get unit file links for %s: %s", name
, bus_error_message(&error
, r
));
6339 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
6341 return bus_log_parse_error(r
);
6343 while ((r
= sd_bus_message_read(reply
, "s", &link
)) > 0)
6344 printf(" %s\n", link
);
6347 return bus_log_parse_error(r
);
6349 r
= sd_bus_message_exit_container(reply
);
6351 return bus_log_parse_error(r
);
6356 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
6358 _cleanup_strv_free_
char **names
= NULL
;
6363 r
= mangle_names(strv_skip(argv
, 1), &names
);
6367 r
= enable_sysv_units(argv
[0], names
);
6373 if (install_client_side()) {
6374 STRV_FOREACH(name
, names
) {
6375 UnitFileState state
;
6377 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
6379 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
6383 UNIT_FILE_ENABLED_RUNTIME
,
6386 UNIT_FILE_GENERATED
))
6390 puts(unit_file_state_to_string(state
));
6392 r
= show_installation_targets_client_side(*name
);
6401 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6404 r
= acquire_bus(BUS_MANAGER
, &bus
);
6408 STRV_FOREACH(name
, names
) {
6409 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6412 r
= sd_bus_call_method(
6414 "org.freedesktop.systemd1",
6415 "/org/freedesktop/systemd1",
6416 "org.freedesktop.systemd1.Manager",
6422 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
6424 r
= sd_bus_message_read(reply
, "s", &s
);
6426 return bus_log_parse_error(r
);
6428 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6434 r
= show_installation_targets(bus
, *name
);
6442 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
6445 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
6446 _cleanup_free_
char *state
= NULL
;
6450 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
6453 return EXIT_FAILURE
;
6456 r
= acquire_bus(BUS_MANAGER
, &bus
);
6460 r
= sd_bus_get_property_string(
6462 "org.freedesktop.systemd1",
6463 "/org/freedesktop/systemd1",
6464 "org.freedesktop.systemd1.Manager",
6477 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
6480 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
6481 _cleanup_free_
char *t
= NULL
;
6485 assert(original_path
);
6488 r
= tempfn_random(new_path
, NULL
, &t
);
6490 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
6492 r
= mkdir_parents(new_path
, 0755);
6494 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
6496 r
= copy_file(original_path
, t
, 0, 0644, 0);
6501 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
6504 return log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", new_path
);
6512 static int get_file_to_edit(
6513 const LookupPaths
*paths
,
6517 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
6522 path
= strjoin(paths
->persistent_config
, "/", name
);
6527 run
= strjoin(paths
->runtime_config
, "/", name
);
6533 if (access(path
, F_OK
) >= 0) {
6534 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
6548 static int unit_file_create_new(
6549 const LookupPaths
*paths
,
6550 const char *unit_name
,
6552 char **ret_new_path
,
6553 char **ret_tmp_path
) {
6555 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6559 assert(ret_new_path
);
6560 assert(ret_tmp_path
);
6562 ending
= strjoina(unit_name
, suffix
);
6563 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
6567 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6573 *ret_new_path
= tmp_new_path
;
6574 *ret_tmp_path
= tmp_tmp_path
;
6579 static int unit_file_create_copy(
6580 const LookupPaths
*paths
,
6581 const char *unit_name
,
6582 const char *fragment_path
,
6583 char **ret_new_path
,
6584 char **ret_tmp_path
) {
6586 char *tmp_new_path
, *tmp_tmp_path
;
6589 assert(fragment_path
);
6591 assert(ret_new_path
);
6592 assert(ret_tmp_path
);
6594 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6598 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6601 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6606 if (response
!= 'y') {
6607 log_warning("%s ignored", unit_name
);
6609 return -EKEYREJECTED
;
6613 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6619 *ret_new_path
= tmp_new_path
;
6620 *ret_tmp_path
= tmp_tmp_path
;
6625 static int run_editor(char **paths
) {
6633 return log_error_errno(errno
, "Failed to fork: %m");
6637 char *editor
, **editor_args
= NULL
;
6638 char **tmp_path
, **original_path
, *p
;
6639 unsigned n_editor_args
= 0, i
= 1;
6642 (void) reset_all_signal_handlers();
6643 (void) reset_signal_mask();
6645 argc
= strv_length(paths
)/2 + 1;
6647 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6648 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6649 * we try to execute well known editors
6651 editor
= getenv("SYSTEMD_EDITOR");
6653 editor
= getenv("EDITOR");
6655 editor
= getenv("VISUAL");
6657 if (!isempty(editor
)) {
6658 editor_args
= strv_split(editor
, WHITESPACE
);
6661 _exit(EXIT_FAILURE
);
6663 n_editor_args
= strv_length(editor_args
);
6664 argc
+= n_editor_args
- 1;
6666 args
= newa(const char*, argc
+ 1);
6668 if (n_editor_args
> 0) {
6669 args
[0] = editor_args
[0];
6670 for (; i
< n_editor_args
; i
++)
6671 args
[i
] = editor_args
[i
];
6674 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6675 args
[i
] = *tmp_path
;
6680 if (n_editor_args
> 0)
6681 execvp(args
[0], (char* const*) args
);
6683 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6685 execvp(p
, (char* const*) args
);
6686 /* We do not fail if the editor doesn't exist
6687 * because we want to try each one of them before
6690 if (errno
!= ENOENT
) {
6691 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6692 _exit(EXIT_FAILURE
);
6696 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6697 _exit(EXIT_FAILURE
);
6700 r
= wait_for_terminate_and_warn("editor", pid
, true);
6702 return log_error_errno(r
, "Failed to wait for child: %m");
6707 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6708 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6715 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6719 STRV_FOREACH(name
, names
) {
6720 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
;
6722 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6725 else if (!arg_force
) {
6727 log_error("Run 'systemctl edit --force %s' to create a new unit.", *name
);
6730 // FIXME: support units with path==NULL (no FragmentPath)
6731 log_error("No fragment exists for %s.", *name
);
6738 r
= unit_file_create_copy(&lp
, *name
, path
, &new_path
, &tmp_path
);
6740 r
= unit_file_create_new(&lp
, *name
, ".d/override.conf", &new_path
, &tmp_path
);
6742 r
= unit_file_create_new(&lp
, *name
, NULL
, &new_path
, &tmp_path
);
6746 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6749 new_path
= tmp_path
= NULL
;
6755 static int edit(int argc
, char *argv
[], void *userdata
) {
6756 _cleanup_strv_free_
char **names
= NULL
;
6757 _cleanup_strv_free_
char **paths
= NULL
;
6758 char **original
, **tmp
;
6763 log_error("Cannot edit units if not on a tty.");
6767 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6768 log_error("Cannot edit units remotely.");
6772 r
= acquire_bus(BUS_MANAGER
, &bus
);
6776 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6778 return log_error_errno(r
, "Failed to expand names: %m");
6780 r
= find_paths_to_edit(bus
, names
, &paths
);
6784 if (strv_isempty(paths
))
6787 r
= run_editor(paths
);
6791 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6792 /* If the temporary file is empty we ignore it. It's
6793 * useful if the user wants to cancel its modification
6795 if (null_or_empty_path(*tmp
)) {
6796 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6800 r
= rename(*tmp
, *original
);
6802 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6809 if (!arg_no_reload
&& !install_client_side())
6810 r
= daemon_reload(argc
, argv
, userdata
);
6813 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6814 (void) unlink(*tmp
);
6816 /* Removing empty dropin dirs */
6818 _cleanup_free_
char *dir
;
6820 dir
= dirname_malloc(*original
);
6824 /* no need to check if the dir is empty, rmdir
6825 * does nothing if it is not the case.
6834 static void systemctl_help(void) {
6836 pager_open(arg_no_pager
, false);
6838 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6839 "Query or send control commands to the systemd manager.\n\n"
6840 " -h --help Show this help\n"
6841 " --version Show package version\n"
6842 " --system Connect to system manager\n"
6843 " --user Connect to user service manager\n"
6844 " -H --host=[USER@]HOST\n"
6845 " Operate on remote host\n"
6846 " -M --machine=CONTAINER\n"
6847 " Operate on local container\n"
6848 " -t --type=TYPE List units of a particular type\n"
6849 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6850 " -p --property=NAME Show only properties by this name\n"
6851 " -a --all Show all properties/all units currently in memory,\n"
6852 " including dead/empty ones. To list all units installed on\n"
6853 " the system, use the 'list-unit-files' command instead.\n"
6854 " -l --full Don't ellipsize unit names on output\n"
6855 " -r --recursive Show unit list of host and local containers\n"
6856 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6857 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6858 " queueing a new job\n"
6859 " --show-types When showing sockets, explicitly show their type\n"
6860 " --value When showing properties, only print the value\n"
6861 " -i --ignore-inhibitors\n"
6862 " When shutting down or sleeping, ignore inhibitors\n"
6863 " --kill-who=WHO Who to send signal to\n"
6864 " -s --signal=SIGNAL Which signal to send\n"
6865 " --now Start or stop unit in addition to enabling or disabling it\n"
6866 " -q --quiet Suppress output\n"
6867 " --wait For (re)start, wait until service stopped again\n"
6868 " --no-block Do not wait until operation finished\n"
6869 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6870 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6871 " --no-legend Do not print a legend (column headers and hints)\n"
6872 " --no-pager Do not pipe output into a pager\n"
6873 " --no-ask-password\n"
6874 " Do not ask for system passwords\n"
6875 " --global Enable/disable unit files globally\n"
6876 " --runtime Enable unit files only temporarily until next reboot\n"
6877 " -f --force When enabling unit files, override existing symlinks\n"
6878 " When shutting down, execute action immediately\n"
6879 " --preset-mode= Apply only enable, only disable, or all presets\n"
6880 " --root=PATH Enable unit files in the specified root directory\n"
6881 " -n --lines=INTEGER Number of journal entries to show\n"
6882 " -o --output=STRING Change journal output mode (short, short-precise,\n"
6883 " short-iso, short-full, short-monotonic, short-unix,\n"
6884 " verbose, export, json, json-pretty, json-sse, cat)\n"
6885 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6886 " --plain Print unit dependencies as a list instead of a tree\n\n"
6888 " list-units [PATTERN...] List units currently in memory\n"
6889 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
6891 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
6893 " start NAME... Start (activate) one or more units\n"
6894 " stop NAME... Stop (deactivate) one or more units\n"
6895 " reload NAME... Reload one or more units\n"
6896 " restart NAME... Start or restart one or more units\n"
6897 " try-restart NAME... Restart one or more units if active\n"
6898 " reload-or-restart NAME... Reload one or more units if possible,\n"
6899 " otherwise start or restart\n"
6900 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6901 " if supported, otherwise restart\n"
6902 " isolate NAME Start one unit and stop all others\n"
6903 " kill NAME... Send signal to processes of a unit\n"
6904 " is-active PATTERN... Check whether units are active\n"
6905 " is-failed PATTERN... Check whether units are failed\n"
6906 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6907 " show [PATTERN...|JOB...] Show properties of one or more\n"
6908 " units/jobs or the manager\n"
6909 " cat PATTERN... Show files and drop-ins of one or more units\n"
6910 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6911 " help PATTERN...|PID... Show manual for one or more units\n"
6912 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6914 " list-dependencies [NAME] Recursively show units which are required\n"
6915 " or wanted by this unit or by which this\n"
6916 " unit is required or wanted\n\n"
6917 "Unit File Commands:\n"
6918 " list-unit-files [PATTERN...] List installed unit files\n"
6919 " enable [NAME...|PATH...] Enable one or more unit files\n"
6920 " disable NAME... Disable one or more unit files\n"
6921 " reenable NAME... Reenable one or more unit files\n"
6922 " preset NAME... Enable/disable one or more unit files\n"
6923 " based on preset configuration\n"
6924 " preset-all Enable/disable all unit files based on\n"
6925 " preset configuration\n"
6926 " is-enabled NAME... Check whether unit files are enabled\n"
6927 " mask NAME... Mask one or more units\n"
6928 " unmask NAME... Unmask one or more units\n"
6929 " link PATH... Link one or more units files into\n"
6930 " the search path\n"
6931 " revert NAME... Revert one or more unit files to vendor\n"
6933 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6934 " on specified one or more units\n"
6935 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6936 " on specified one or more units\n"
6937 " edit NAME... Edit one or more unit files\n"
6938 " get-default Get the name of the default target\n"
6939 " set-default NAME Set the default target\n\n"
6940 "Machine Commands:\n"
6941 " list-machines [PATTERN...] List local containers and host\n\n"
6943 " list-jobs [PATTERN...] List jobs\n"
6944 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6945 "Environment Commands:\n"
6946 " show-environment Dump environment\n"
6947 " set-environment NAME=VALUE... Set one or more environment variables\n"
6948 " unset-environment NAME... Unset one or more environment variables\n"
6949 " import-environment [NAME...] Import all or some environment variables\n\n"
6950 "Manager Lifecycle Commands:\n"
6951 " daemon-reload Reload systemd manager configuration\n"
6952 " daemon-reexec Reexecute systemd manager\n\n"
6953 "System Commands:\n"
6954 " is-system-running Check whether system is fully running\n"
6955 " default Enter system default mode\n"
6956 " rescue Enter system rescue mode\n"
6957 " emergency Enter system emergency mode\n"
6958 " halt Shut down and halt the system\n"
6959 " poweroff Shut down and power-off the system\n"
6960 " reboot [ARG] Shut down and reboot the system\n"
6961 " kexec Shut down and reboot the system with kexec\n"
6962 " exit [EXIT_CODE] Request user instance or container exit\n"
6963 " switch-root ROOT [INIT] Change to a different root file system\n"
6964 " suspend Suspend the system\n"
6965 " hibernate Hibernate the system\n"
6966 " hybrid-sleep Hibernate and suspend the system\n",
6967 program_invocation_short_name
);
6970 static void halt_help(void) {
6971 printf("%s [OPTIONS...]%s\n\n"
6972 "%s the system.\n\n"
6973 " --help Show this help\n"
6974 " --halt Halt the machine\n"
6975 " -p --poweroff Switch off the machine\n"
6976 " --reboot Reboot the machine\n"
6977 " -f --force Force immediate halt/power-off/reboot\n"
6978 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6979 " -d --no-wtmp Don't write wtmp record\n"
6980 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6981 program_invocation_short_name
,
6982 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6983 arg_action
== ACTION_REBOOT
? "Reboot" :
6984 arg_action
== ACTION_POWEROFF
? "Power off" :
6988 static void shutdown_help(void) {
6989 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6990 "Shut down the system.\n\n"
6991 " --help Show this help\n"
6992 " -H --halt Halt the machine\n"
6993 " -P --poweroff Power-off the machine\n"
6994 " -r --reboot Reboot the machine\n"
6995 " -h Equivalent to --poweroff, overridden by --halt\n"
6996 " -k Don't halt/power-off/reboot, just send warnings\n"
6997 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6998 " -c Cancel a pending shutdown\n",
6999 program_invocation_short_name
);
7002 static void telinit_help(void) {
7003 printf("%s [OPTIONS...] {COMMAND}\n\n"
7004 "Send control commands to the init daemon.\n\n"
7005 " --help Show this help\n"
7006 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7008 " 0 Power-off the machine\n"
7009 " 6 Reboot the machine\n"
7010 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7011 " 1, s, S Enter rescue mode\n"
7012 " q, Q Reload init daemon configuration\n"
7013 " u, U Reexecute init daemon\n",
7014 program_invocation_short_name
);
7017 static void runlevel_help(void) {
7018 printf("%s [OPTIONS...]\n\n"
7019 "Prints the previous and current runlevel of the init system.\n\n"
7020 " --help Show this help\n",
7021 program_invocation_short_name
);
7024 static void help_types(void) {
7028 puts("Available unit types:");
7029 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
7030 puts(unit_type_to_string(i
));
7033 static void help_states(void) {
7037 puts("Available unit load states:");
7038 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
7039 puts(unit_load_state_to_string(i
));
7042 puts("\nAvailable unit active states:");
7043 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
7044 puts(unit_active_state_to_string(i
));
7047 puts("\nAvailable automount unit substates:");
7048 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
7049 puts(automount_state_to_string(i
));
7052 puts("\nAvailable busname unit substates:");
7053 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
7054 puts(busname_state_to_string(i
));
7057 puts("\nAvailable device unit substates:");
7058 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
7059 puts(device_state_to_string(i
));
7062 puts("\nAvailable mount unit substates:");
7063 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
7064 puts(mount_state_to_string(i
));
7067 puts("\nAvailable path unit substates:");
7068 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
7069 puts(path_state_to_string(i
));
7072 puts("\nAvailable scope unit substates:");
7073 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
7074 puts(scope_state_to_string(i
));
7077 puts("\nAvailable service unit substates:");
7078 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
7079 puts(service_state_to_string(i
));
7082 puts("\nAvailable slice unit substates:");
7083 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
7084 puts(slice_state_to_string(i
));
7087 puts("\nAvailable socket unit substates:");
7088 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
7089 puts(socket_state_to_string(i
));
7092 puts("\nAvailable swap unit substates:");
7093 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
7094 puts(swap_state_to_string(i
));
7097 puts("\nAvailable target unit substates:");
7098 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
7099 puts(target_state_to_string(i
));
7102 puts("\nAvailable timer unit substates:");
7103 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
7104 puts(timer_state_to_string(i
));
7107 static int systemctl_parse_argv(int argc
, char *argv
[]) {
7116 ARG_IGNORE_DEPENDENCIES
,
7129 ARG_NO_ASK_PASSWORD
,
7143 static const struct option options
[] = {
7144 { "help", no_argument
, NULL
, 'h' },
7145 { "version", no_argument
, NULL
, ARG_VERSION
},
7146 { "type", required_argument
, NULL
, 't' },
7147 { "property", required_argument
, NULL
, 'p' },
7148 { "all", no_argument
, NULL
, 'a' },
7149 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
7150 { "after", no_argument
, NULL
, ARG_AFTER
},
7151 { "before", no_argument
, NULL
, ARG_BEFORE
},
7152 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
7153 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
7154 { "full", no_argument
, NULL
, 'l' },
7155 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
7156 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
7157 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
7158 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
7159 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
7160 { "value", no_argument
, NULL
, ARG_VALUE
},
7161 { "user", no_argument
, NULL
, ARG_USER
},
7162 { "system", no_argument
, NULL
, ARG_SYSTEM
},
7163 { "global", no_argument
, NULL
, ARG_GLOBAL
},
7164 { "wait", no_argument
, NULL
, ARG_WAIT
},
7165 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
7166 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
7167 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
7168 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7169 { "quiet", no_argument
, NULL
, 'q' },
7170 { "root", required_argument
, NULL
, ARG_ROOT
},
7171 { "force", no_argument
, NULL
, ARG_FORCE
},
7172 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
7173 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
7174 { "signal", required_argument
, NULL
, 's' },
7175 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
7176 { "host", required_argument
, NULL
, 'H' },
7177 { "machine", required_argument
, NULL
, 'M' },
7178 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
7179 { "lines", required_argument
, NULL
, 'n' },
7180 { "output", required_argument
, NULL
, 'o' },
7181 { "plain", no_argument
, NULL
, ARG_PLAIN
},
7182 { "state", required_argument
, NULL
, ARG_STATE
},
7183 { "recursive", no_argument
, NULL
, 'r' },
7184 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
7185 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
7186 { "now", no_argument
, NULL
, ARG_NOW
},
7187 { "message", required_argument
, NULL
, ARG_MESSAGE
},
7197 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7198 arg_ask_password
= true;
7200 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
7212 if (isempty(optarg
)) {
7213 log_error("--type requires arguments.");
7219 _cleanup_free_
char *type
= NULL
;
7221 r
= extract_first_word(&p
, &type
, ",", 0);
7223 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
7228 if (streq(type
, "help")) {
7233 if (unit_type_from_string(type
) >= 0) {
7234 if (strv_push(&arg_types
, type
) < 0)
7240 /* It's much nicer to use --state= for
7241 * load states, but let's support this
7242 * in --types= too for compatibility
7243 * with old versions */
7244 if (unit_load_state_from_string(type
) >= 0) {
7245 if (strv_push(&arg_states
, type
) < 0)
7251 log_error("Unknown unit type or load state '%s'.", type
);
7252 log_info("Use -t help to see a list of allowed values.");
7260 /* Make sure that if the empty property list
7261 was specified, we won't show any properties. */
7262 if (isempty(optarg
) && !arg_properties
) {
7263 arg_properties
= new0(char*, 1);
7264 if (!arg_properties
)
7269 _cleanup_free_
char *prop
= NULL
;
7271 r
= extract_first_word(&p
, &prop
, ",", 0);
7273 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
7278 if (strv_push(&arg_properties
, prop
) < 0)
7285 /* If the user asked for a particular
7286 * property, show it to him, even if it is
7298 arg_dependency
= DEPENDENCY_REVERSE
;
7302 arg_dependency
= DEPENDENCY_AFTER
;
7306 arg_dependency
= DEPENDENCY_BEFORE
;
7309 case ARG_SHOW_TYPES
:
7310 arg_show_types
= true;
7318 arg_job_mode
= optarg
;
7322 arg_job_mode
= "fail";
7325 case ARG_IRREVERSIBLE
:
7326 arg_job_mode
= "replace-irreversibly";
7329 case ARG_IGNORE_DEPENDENCIES
:
7330 arg_job_mode
= "ignore-dependencies";
7334 arg_scope
= UNIT_FILE_USER
;
7338 arg_scope
= UNIT_FILE_SYSTEM
;
7342 arg_scope
= UNIT_FILE_GLOBAL
;
7350 arg_no_block
= true;
7354 arg_no_legend
= true;
7358 arg_no_pager
= true;
7366 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
7376 if (strv_extend(&arg_states
, "failed") < 0)
7394 arg_no_reload
= true;
7398 arg_kill_who
= optarg
;
7402 arg_signal
= signal_from_string_try_harder(optarg
);
7403 if (arg_signal
< 0) {
7404 log_error("Failed to parse signal string %s.", optarg
);
7409 case ARG_NO_ASK_PASSWORD
:
7410 arg_ask_password
= false;
7414 arg_transport
= BUS_TRANSPORT_REMOTE
;
7419 arg_transport
= BUS_TRANSPORT_MACHINE
;
7428 if (safe_atou(optarg
, &arg_lines
) < 0) {
7429 log_error("Failed to parse lines '%s'", optarg
);
7435 arg_output
= output_mode_from_string(optarg
);
7436 if (arg_output
< 0) {
7437 log_error("Unknown output '%s'.", optarg
);
7443 arg_ignore_inhibitors
= true;
7450 case ARG_FIRMWARE_SETUP
:
7451 arg_firmware_setup
= true;
7455 if (isempty(optarg
)) {
7456 log_error("--signal requires arguments.");
7462 _cleanup_free_
char *s
= NULL
;
7464 r
= extract_first_word(&p
, &s
, ",", 0);
7466 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
7471 if (streq(s
, "help")) {
7476 if (strv_push(&arg_states
, s
) < 0)
7485 if (geteuid() != 0) {
7486 log_error("--recursive requires root privileges.");
7490 arg_recursive
= true;
7493 case ARG_PRESET_MODE
:
7495 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
7496 if (arg_preset_mode
< 0) {
7497 log_error("Failed to parse preset mode: %s.", optarg
);
7508 if (strv_extend(&arg_wall
, optarg
) < 0)
7516 assert_not_reached("Unhandled option");
7519 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
7520 log_error("Cannot access user instance remotely.");
7524 if (arg_wait
&& arg_no_block
) {
7525 log_error("--wait may not be combined with --no-block.");
7532 static int halt_parse_argv(int argc
, char *argv
[]) {
7541 static const struct option options
[] = {
7542 { "help", no_argument
, NULL
, ARG_HELP
},
7543 { "halt", no_argument
, NULL
, ARG_HALT
},
7544 { "poweroff", no_argument
, NULL
, 'p' },
7545 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
7546 { "force", no_argument
, NULL
, 'f' },
7547 { "wtmp-only", no_argument
, NULL
, 'w' },
7548 { "no-wtmp", no_argument
, NULL
, 'd' },
7549 { "no-sync", no_argument
, NULL
, 'n' },
7550 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7559 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
7560 if (runlevel
== '0' || runlevel
== '6')
7563 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
7571 arg_action
= ACTION_HALT
;
7575 if (arg_action
!= ACTION_REBOOT
)
7576 arg_action
= ACTION_POWEROFF
;
7580 arg_action
= ACTION_REBOOT
;
7605 /* Compatibility nops */
7612 assert_not_reached("Unhandled option");
7615 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7616 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7619 } else if (optind
< argc
) {
7620 log_error("Too many arguments.");
7627 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7631 if (streq(t
, "now"))
7633 else if (!strchr(t
, ':')) {
7636 if (safe_atou64(t
, &u
) < 0)
7639 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7648 hour
= strtol(t
, &e
, 10);
7649 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7652 minute
= strtol(e
+1, &e
, 10);
7653 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7656 n
= now(CLOCK_REALTIME
);
7657 s
= (time_t) (n
/ USEC_PER_SEC
);
7659 assert_se(localtime_r(&s
, &tm
));
7661 tm
.tm_hour
= (int) hour
;
7662 tm
.tm_min
= (int) minute
;
7665 assert_se(s
= mktime(&tm
));
7667 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7670 *_u
+= USEC_PER_DAY
;
7676 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7683 static const struct option options
[] = {
7684 { "help", no_argument
, NULL
, ARG_HELP
},
7685 { "halt", no_argument
, NULL
, 'H' },
7686 { "poweroff", no_argument
, NULL
, 'P' },
7687 { "reboot", no_argument
, NULL
, 'r' },
7688 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7689 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7699 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7707 arg_action
= ACTION_HALT
;
7711 arg_action
= ACTION_POWEROFF
;
7716 arg_action
= ACTION_KEXEC
;
7718 arg_action
= ACTION_REBOOT
;
7722 arg_action
= ACTION_KEXEC
;
7726 if (arg_action
!= ACTION_HALT
)
7727 arg_action
= ACTION_POWEROFF
;
7742 /* Compatibility nops */
7746 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7753 assert_not_reached("Unhandled option");
7756 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7757 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7759 log_error("Failed to parse time specification: %s", argv
[optind
]);
7763 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7765 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7766 /* No time argument for shutdown cancel */
7767 wall
= argv
+ optind
;
7768 else if (argc
> optind
+ 1)
7769 /* We skip the time argument */
7770 wall
= argv
+ optind
+ 1;
7773 arg_wall
= strv_copy(wall
);
7783 static int telinit_parse_argv(int argc
, char *argv
[]) {
7790 static const struct option options
[] = {
7791 { "help", no_argument
, NULL
, ARG_HELP
},
7792 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7796 static const struct {
7800 { '0', ACTION_POWEROFF
},
7801 { '6', ACTION_REBOOT
},
7802 { '1', ACTION_RESCUE
},
7803 { '2', ACTION_RUNLEVEL2
},
7804 { '3', ACTION_RUNLEVEL3
},
7805 { '4', ACTION_RUNLEVEL4
},
7806 { '5', ACTION_RUNLEVEL5
},
7807 { 's', ACTION_RESCUE
},
7808 { 'S', ACTION_RESCUE
},
7809 { 'q', ACTION_RELOAD
},
7810 { 'Q', ACTION_RELOAD
},
7811 { 'u', ACTION_REEXEC
},
7812 { 'U', ACTION_REEXEC
}
7821 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7836 assert_not_reached("Unhandled option");
7839 if (optind
>= argc
) {
7840 log_error("%s: required argument missing.", program_invocation_short_name
);
7844 if (optind
+ 1 < argc
) {
7845 log_error("Too many arguments.");
7849 if (strlen(argv
[optind
]) != 1) {
7850 log_error("Expected single character argument.");
7854 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7855 if (table
[i
].from
== argv
[optind
][0])
7858 if (i
>= ELEMENTSOF(table
)) {
7859 log_error("Unknown command '%s'.", argv
[optind
]);
7863 arg_action
= table
[i
].to
;
7870 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7876 static const struct option options
[] = {
7877 { "help", no_argument
, NULL
, ARG_HELP
},
7886 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7897 assert_not_reached("Unhandled option");
7900 if (optind
< argc
) {
7901 log_error("Too many arguments.");
7908 static int parse_argv(int argc
, char *argv
[]) {
7912 if (program_invocation_short_name
) {
7914 if (strstr(program_invocation_short_name
, "halt")) {
7915 arg_action
= ACTION_HALT
;
7916 return halt_parse_argv(argc
, argv
);
7917 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7918 arg_action
= ACTION_POWEROFF
;
7919 return halt_parse_argv(argc
, argv
);
7920 } else if (strstr(program_invocation_short_name
, "reboot")) {
7922 arg_action
= ACTION_KEXEC
;
7924 arg_action
= ACTION_REBOOT
;
7925 return halt_parse_argv(argc
, argv
);
7926 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7927 arg_action
= ACTION_POWEROFF
;
7928 return shutdown_parse_argv(argc
, argv
);
7929 } else if (strstr(program_invocation_short_name
, "init")) {
7931 if (sd_booted() > 0) {
7932 arg_action
= _ACTION_INVALID
;
7933 return telinit_parse_argv(argc
, argv
);
7935 /* Hmm, so some other init system is
7936 * running, we need to forward this
7937 * request to it. For now we simply
7938 * guess that it is Upstart. */
7940 execv(TELINIT
, argv
);
7942 log_error("Couldn't find an alternative telinit implementation to spawn.");
7946 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7947 arg_action
= ACTION_RUNLEVEL
;
7948 return runlevel_parse_argv(argc
, argv
);
7952 arg_action
= ACTION_SYSTEMCTL
;
7953 return systemctl_parse_argv(argc
, argv
);
7956 #ifdef HAVE_SYSV_COMPAT
7957 _pure_
static int action_to_runlevel(void) {
7959 static const char table
[_ACTION_MAX
] = {
7960 [ACTION_HALT
] = '0',
7961 [ACTION_POWEROFF
] = '0',
7962 [ACTION_REBOOT
] = '6',
7963 [ACTION_RUNLEVEL2
] = '2',
7964 [ACTION_RUNLEVEL3
] = '3',
7965 [ACTION_RUNLEVEL4
] = '4',
7966 [ACTION_RUNLEVEL5
] = '5',
7967 [ACTION_RESCUE
] = '1'
7970 assert(arg_action
< _ACTION_MAX
);
7972 return table
[arg_action
];
7976 static int talk_initctl(void) {
7977 #ifdef HAVE_SYSV_COMPAT
7978 struct init_request request
= {
7979 .magic
= INIT_MAGIC
,
7981 .cmd
= INIT_CMD_RUNLVL
7984 _cleanup_close_
int fd
= -1;
7988 rl
= action_to_runlevel();
7992 request
.runlevel
= rl
;
7994 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7996 if (errno
== ENOENT
)
7999 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
8002 r
= loop_write(fd
, &request
, sizeof(request
), false);
8004 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
8012 static int systemctl_main(int argc
, char *argv
[]) {
8014 static const Verb verbs
[] = {
8015 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
8016 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
8017 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
8018 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
8019 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
8020 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
8021 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, trivial_method
},
8022 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
8023 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8024 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8025 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8026 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8027 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8028 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8029 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8030 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
8031 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8032 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
8033 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8034 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
8035 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
8036 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
8037 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8038 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8039 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
8040 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8041 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
8042 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8043 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8044 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8045 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8046 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
8047 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8048 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8049 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
8050 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8051 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8052 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_system_special
},
8053 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8054 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8055 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8056 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8057 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
8058 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8059 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8060 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
8061 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
8062 { "enable", 2, VERB_ANY
, 0, enable_unit
},
8063 { "disable", 2, VERB_ANY
, 0, enable_unit
},
8064 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
8065 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
8066 { "preset", 2, VERB_ANY
, 0, enable_unit
},
8067 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
8068 { "mask", 2, VERB_ANY
, 0, enable_unit
},
8069 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
8070 { "link", 2, VERB_ANY
, 0, enable_unit
},
8071 { "revert", 2, VERB_ANY
, 0, enable_unit
},
8072 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
8073 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
8074 { "set-default", 2, 2, 0, set_default
},
8075 { "get-default", VERB_ANY
, 1, 0, get_default
},
8076 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
8077 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
8078 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
8079 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
8080 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
8084 return dispatch_verb(argc
, argv
, verbs
, NULL
);
8087 static int reload_with_fallback(void) {
8089 /* First, try systemd via D-Bus. */
8090 if (daemon_reload(0, NULL
, NULL
) >= 0)
8093 /* Nothing else worked, so let's try signals */
8094 assert(IN_SET(arg_action
, ACTION_RELOAD
, ACTION_REEXEC
));
8096 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
8097 return log_error_errno(errno
, "kill() failed: %m");
8102 static int start_with_fallback(void) {
8104 /* First, try systemd via D-Bus. */
8105 if (start_unit(0, NULL
, NULL
) >= 0)
8108 /* Nothing else worked, so let's try /dev/initctl */
8109 if (talk_initctl() > 0)
8112 log_error("Failed to talk to init daemon.");
8116 static int halt_now(enum action a
) {
8119 /* The kernel will automaticall flush ATA disks and suchlike
8120 * on reboot(), but the file systems need to be synce'd
8121 * explicitly in advance. */
8125 /* Make sure C-A-D is handled by the kernel from this point
8127 (void) reboot(RB_ENABLE_CAD
);
8132 log_info("Halting.");
8133 (void) reboot(RB_HALT_SYSTEM
);
8136 case ACTION_POWEROFF
:
8137 log_info("Powering off.");
8138 (void) reboot(RB_POWER_OFF
);
8142 case ACTION_REBOOT
: {
8143 _cleanup_free_
char *param
= NULL
;
8145 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
8147 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
8149 if (!isempty(param
)) {
8150 log_info("Rebooting with argument '%s'.", param
);
8151 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
8152 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
8155 log_info("Rebooting.");
8156 (void) reboot(RB_AUTOBOOT
);
8161 assert_not_reached("Unknown action.");
8165 static int logind_schedule_shutdown(void) {
8168 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8169 char date
[FORMAT_TIMESTAMP_MAX
];
8174 r
= acquire_bus(BUS_FULL
, &bus
);
8178 switch (arg_action
) {
8182 case ACTION_POWEROFF
:
8183 action
= "poweroff";
8198 action
= strjoina("dry-", action
);
8200 (void) logind_set_wall_message();
8202 r
= sd_bus_call_method(
8204 "org.freedesktop.login1",
8205 "/org/freedesktop/login1",
8206 "org.freedesktop.login1.Manager",
8214 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
8216 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
8219 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8224 static int halt_main(void) {
8227 r
= logind_check_inhibitors(arg_action
);
8232 return logind_schedule_shutdown();
8234 if (geteuid() != 0) {
8235 if (arg_dry
|| arg_force
> 0) {
8236 log_error("Must be root.");
8240 /* Try logind if we are a normal user and no special
8241 * mode applies. Maybe PolicyKit allows us to shutdown
8243 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
8244 r
= logind_reboot(arg_action
);
8247 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
8248 /* requested operation is not
8249 * supported on the local system or
8250 * already in progress */
8252 /* on all other errors, try low-level operation */
8256 if (!arg_dry
&& !arg_force
)
8257 return start_with_fallback();
8259 assert(geteuid() == 0);
8262 if (sd_booted() > 0)
8263 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8265 r
= utmp_put_shutdown();
8267 log_warning_errno(r
, "Failed to write utmp record: %m");
8274 r
= halt_now(arg_action
);
8275 return log_error_errno(r
, "Failed to reboot: %m");
8278 static int runlevel_main(void) {
8279 int r
, runlevel
, previous
;
8281 r
= utmp_get_runlevel(&runlevel
, &previous
);
8288 previous
<= 0 ? 'N' : previous
,
8289 runlevel
<= 0 ? 'N' : runlevel
);
8294 static int logind_cancel_shutdown(void) {
8296 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8300 r
= acquire_bus(BUS_FULL
, &bus
);
8304 (void) logind_set_wall_message();
8306 r
= sd_bus_call_method(
8308 "org.freedesktop.login1",
8309 "/org/freedesktop/login1",
8310 "org.freedesktop.login1.Manager",
8311 "CancelScheduledShutdown",
8315 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
8319 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8324 int main(int argc
, char*argv
[]) {
8327 setlocale(LC_ALL
, "");
8328 log_parse_environment();
8332 /* Explicitly not on_tty() to avoid setting cached value.
8333 * This becomes relevant for piping output which might be
8335 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
8337 r
= parse_argv(argc
, argv
);
8341 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
8342 log_info("Running in chroot, ignoring request.");
8347 /* systemctl_main() will print an error message for the bus
8348 * connection, but only if it needs to */
8350 switch (arg_action
) {
8352 case ACTION_SYSTEMCTL
:
8353 r
= systemctl_main(argc
, argv
);
8357 case ACTION_POWEROFF
:
8363 case ACTION_RUNLEVEL2
:
8364 case ACTION_RUNLEVEL3
:
8365 case ACTION_RUNLEVEL4
:
8366 case ACTION_RUNLEVEL5
:
8368 case ACTION_EMERGENCY
:
8369 case ACTION_DEFAULT
:
8370 r
= start_with_fallback();
8375 r
= reload_with_fallback();
8378 case ACTION_CANCEL_SHUTDOWN
:
8379 r
= logind_cancel_shutdown();
8382 case ACTION_RUNLEVEL
:
8383 r
= runlevel_main();
8386 case _ACTION_INVALID
:
8388 assert_not_reached("Unknown action");
8395 ask_password_agent_close();
8396 polkit_agent_close();
8398 strv_free(arg_types
);
8399 strv_free(arg_states
);
8400 strv_free(arg_properties
);
8402 strv_free(arg_wall
);
8405 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8406 return r
< 0 ? EXIT_FAILURE
: r
;