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"
73 #include "signal-util.h"
74 #include "socket-util.h"
75 #include "spawn-ask-password-agent.h"
76 #include "spawn-polkit-agent.h"
78 #include "stat-util.h"
80 #include "terminal-util.h"
81 #include "unit-name.h"
82 #include "user-util.h"
84 #include "utmp-wtmp.h"
88 static char **arg_types
= NULL
;
89 static char **arg_states
= NULL
;
90 static char **arg_properties
= NULL
;
91 static bool arg_all
= false;
92 static enum dependency
{
98 } arg_dependency
= DEPENDENCY_FORWARD
;
99 static const char *arg_job_mode
= "replace";
100 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
101 static bool arg_no_block
= false;
102 static bool arg_no_legend
= false;
103 static bool arg_no_pager
= false;
104 static bool arg_no_wtmp
= false;
105 static bool arg_no_sync
= false;
106 static bool arg_no_wall
= false;
107 static bool arg_no_reload
= false;
108 static bool arg_value
= false;
109 static bool arg_show_types
= false;
110 static bool arg_ignore_inhibitors
= false;
111 static bool arg_dry
= false;
112 static bool arg_quiet
= false;
113 static bool arg_full
= false;
114 static bool arg_recursive
= false;
115 static int arg_force
= 0;
116 static bool arg_ask_password
= false;
117 static bool arg_runtime
= false;
118 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
119 static char **arg_wall
= NULL
;
120 static const char *arg_kill_who
= NULL
;
121 static int arg_signal
= SIGTERM
;
122 static char *arg_root
= NULL
;
123 static usec_t arg_when
= 0;
145 ACTION_CANCEL_SHUTDOWN
,
147 } arg_action
= ACTION_SYSTEMCTL
;
148 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
149 static const char *arg_host
= NULL
;
150 static unsigned arg_lines
= 10;
151 static OutputMode arg_output
= OUTPUT_SHORT
;
152 static bool arg_plain
= false;
153 static bool arg_firmware_setup
= false;
154 static bool arg_now
= false;
156 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
157 static int halt_now(enum action a
);
158 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
160 static bool original_stdout_is_tty
;
162 typedef enum BusFocus
{
163 BUS_FULL
, /* The full bus indicated via --system or --user */
164 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
168 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
170 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
173 assert(focus
< _BUS_FOCUS_MAX
);
176 /* We only go directly to the manager, if we are using a local transport */
177 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
180 if (!busses
[focus
]) {
183 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
185 if (focus
== BUS_MANAGER
)
186 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
188 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
190 return log_error_errno(r
, "Failed to connect to bus: %m");
192 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
195 *ret
= busses
[focus
];
199 static void release_busses(void) {
202 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
203 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
206 static void ask_password_agent_open_if_enabled(void) {
208 /* Open the password agent as a child process if necessary */
210 if (!arg_ask_password
)
213 if (arg_scope
!= UNIT_FILE_SYSTEM
)
216 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
219 ask_password_agent_open();
222 static void polkit_agent_open_if_enabled(void) {
224 /* Open the polkit agent as a child process if necessary */
226 if (!arg_ask_password
)
229 if (arg_scope
!= UNIT_FILE_SYSTEM
)
232 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
238 static OutputFlags
get_output_flags(void) {
240 arg_all
* OUTPUT_SHOW_ALL
|
241 arg_full
* OUTPUT_FULL_WIDTH
|
242 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
243 colors_enabled() * OUTPUT_COLOR
|
244 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
247 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
250 if (!sd_bus_error_is_set(error
))
253 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
254 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
255 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
256 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
257 return EXIT_NOPERMISSION
;
259 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
260 return EXIT_NOTINSTALLED
;
262 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
263 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
264 return EXIT_NOTIMPLEMENTED
;
266 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
267 return EXIT_NOTCONFIGURED
;
275 static bool install_client_side(void) {
277 /* Decides when to execute enable/disable/... operations
278 * client-side rather than server-side. */
280 if (running_in_chroot() > 0)
283 if (sd_booted() <= 0)
286 if (!isempty(arg_root
))
289 if (arg_scope
== UNIT_FILE_GLOBAL
)
292 /* Unsupported environment variable, mostly for debugging purposes */
293 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
299 static int compare_unit_info(const void *a
, const void *b
) {
300 const UnitInfo
*u
= a
, *v
= b
;
304 /* First, order by machine */
305 if (!u
->machine
&& v
->machine
)
307 if (u
->machine
&& !v
->machine
)
309 if (u
->machine
&& v
->machine
) {
310 r
= strcasecmp(u
->machine
, v
->machine
);
315 /* Second, order by unit type */
316 d1
= strrchr(u
->id
, '.');
317 d2
= strrchr(v
->id
, '.');
319 r
= strcasecmp(d1
, d2
);
324 /* Third, order by name */
325 return strcasecmp(u
->id
, v
->id
);
328 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
331 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
337 dot
= strrchr(u
->id
, '.');
341 if (!strv_find(arg_types
, dot
+1))
348 /* Note that '--all' is not purely a state filter, but also a
349 * filter that hides units that "follow" other units (which is
350 * used for device units that appear under different names). */
351 if (!isempty(u
->following
))
354 if (!strv_isempty(arg_states
))
357 /* By default show all units except the ones in inactive
358 * state and with no pending job */
362 if (streq(u
->active_state
, "inactive"))
368 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
369 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
371 unsigned n_shown
= 0;
374 max_id_len
= strlen("UNIT");
375 load_len
= strlen("LOAD");
376 active_len
= strlen("ACTIVE");
377 sub_len
= strlen("SUB");
378 job_len
= strlen("JOB");
381 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
382 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
383 load_len
= MAX(load_len
, strlen(u
->load_state
));
384 active_len
= MAX(active_len
, strlen(u
->active_state
));
385 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
387 if (u
->job_id
!= 0) {
388 job_len
= MAX(job_len
, strlen(u
->job_type
));
392 if (!arg_no_legend
&&
393 (streq(u
->active_state
, "failed") ||
394 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
398 if (!arg_full
&& original_stdout_is_tty
) {
401 id_len
= MIN(max_id_len
, 25u);
402 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
405 basic_len
+= job_len
+ 1;
407 if (basic_len
< (unsigned) columns()) {
408 unsigned extra_len
, incr
;
409 extra_len
= columns() - basic_len
;
411 /* Either UNIT already got 25, or is fully satisfied.
412 * Grant up to 25 to DESC now. */
413 incr
= MIN(extra_len
, 25u);
417 /* split the remaining space between UNIT and DESC,
418 * but do not give UNIT more than it needs. */
420 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
422 desc_len
+= extra_len
- incr
;
428 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
429 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
430 const char *on_loaded
= "", *off_loaded
= "";
431 const char *on_active
= "", *off_active
= "";
432 const char *on_circle
= "", *off_circle
= "";
436 if (!n_shown
&& !arg_no_legend
) {
441 printf("%-*s %-*s %-*s %-*s ",
444 active_len
, "ACTIVE",
448 printf("%-*s ", job_len
, "JOB");
450 if (!arg_full
&& arg_no_pager
)
451 printf("%.*s\n", desc_len
, "DESCRIPTION");
453 printf("%s\n", "DESCRIPTION");
458 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
459 on_loaded
= ansi_highlight_red();
460 on_circle
= ansi_highlight_yellow();
461 off_loaded
= off_circle
= ansi_normal();
463 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
464 on_circle
= on_active
= ansi_highlight_red();
465 off_circle
= off_active
= ansi_normal();
470 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
479 e
= ellipsize(id
, id_len
, 33);
487 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
489 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
490 on_active
, id_len
, id
, off_active
,
491 on_loaded
, load_len
, u
->load_state
, off_loaded
,
492 on_active
, active_len
, u
->active_state
,
493 sub_len
, u
->sub_state
, off_active
,
494 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
497 printf("%.*s\n", desc_len
, u
->description
);
499 printf("%s\n", u
->description
);
502 if (!arg_no_legend
) {
503 const char *on
, *off
;
507 "LOAD = Reflects whether the unit definition was properly loaded.\n"
508 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
509 "SUB = The low-level unit activation state, values depend on unit type.");
510 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
511 on
= ansi_highlight();
514 on
= ansi_highlight_red();
519 printf("%s%u loaded units listed.%s\n"
520 "To show all installed unit files use 'systemctl list-unit-files'.\n",
523 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
524 "To show all installed unit files use 'systemctl list-unit-files'.\n",
531 static int get_unit_list(
535 UnitInfo
**unit_infos
,
537 sd_bus_message
**_reply
) {
539 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
540 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
541 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
545 bool fallback
= false;
551 r
= sd_bus_message_new_method_call(
554 "org.freedesktop.systemd1",
555 "/org/freedesktop/systemd1",
556 "org.freedesktop.systemd1.Manager",
557 "ListUnitsByPatterns");
559 return bus_log_create_error(r
);
561 r
= sd_bus_message_append_strv(m
, arg_states
);
563 return bus_log_create_error(r
);
565 r
= sd_bus_message_append_strv(m
, patterns
);
567 return bus_log_create_error(r
);
569 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
570 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
571 /* Fallback to legacy ListUnitsFiltered method */
573 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
574 m
= sd_bus_message_unref(m
);
575 sd_bus_error_free(&error
);
577 r
= sd_bus_message_new_method_call(
580 "org.freedesktop.systemd1",
581 "/org/freedesktop/systemd1",
582 "org.freedesktop.systemd1.Manager",
583 "ListUnitsFiltered");
585 return bus_log_create_error(r
);
587 r
= sd_bus_message_append_strv(m
, arg_states
);
589 return bus_log_create_error(r
);
591 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
594 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
596 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
598 return bus_log_parse_error(r
);
600 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
603 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
606 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
609 (*unit_infos
)[c
++] = u
;
612 return bus_log_parse_error(r
);
614 r
= sd_bus_message_exit_container(reply
);
616 return bus_log_parse_error(r
);
624 static void message_set_freep(Set
**set
) {
627 while ((m
= set_steal_first(*set
)))
628 sd_bus_message_unref(m
);
633 static int get_unit_list_recursive(
636 UnitInfo
**_unit_infos
,
640 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
641 _cleanup_(message_set_freep
) Set
*replies
;
642 sd_bus_message
*reply
;
650 replies
= set_new(NULL
);
654 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
658 r
= set_put(replies
, reply
);
660 sd_bus_message_unref(reply
);
665 _cleanup_strv_free_
char **machines
= NULL
;
668 r
= sd_get_machine_names(&machines
);
670 return log_error_errno(r
, "Failed to get machine names: %m");
672 STRV_FOREACH(i
, machines
) {
673 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
676 r
= sd_bus_open_system_machine(&container
, *i
);
678 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
682 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
688 r
= set_put(replies
, reply
);
690 sd_bus_message_unref(reply
);
695 *_machines
= machines
;
700 *_unit_infos
= unit_infos
;
709 static int list_units(int argc
, char *argv
[], void *userdata
) {
710 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
711 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
712 _cleanup_strv_free_
char **machines
= NULL
;
716 pager_open(arg_no_pager
, false);
718 r
= acquire_bus(BUS_MANAGER
, &bus
);
722 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
726 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
727 return output_units_list(unit_infos
, r
);
730 static int get_triggered_units(
735 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
742 r
= sd_bus_get_property_strv(
744 "org.freedesktop.systemd1",
746 "org.freedesktop.systemd1.Unit",
751 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
756 static int get_listening(
758 const char* unit_path
,
761 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
762 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
763 const char *type
, *path
;
766 r
= sd_bus_get_property(
768 "org.freedesktop.systemd1",
770 "org.freedesktop.systemd1.Socket",
776 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
778 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
780 return bus_log_parse_error(r
);
782 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
784 r
= strv_extend(listening
, type
);
788 r
= strv_extend(listening
, path
);
795 return bus_log_parse_error(r
);
797 r
= sd_bus_message_exit_container(reply
);
799 return bus_log_parse_error(r
);
811 /* Note: triggered is a list here, although it almost certainly
812 * will always be one unit. Nevertheless, dbus API allows for multiple
813 * values, so let's follow that. */
816 /* The strv above is shared. free is set only in the first one. */
820 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
826 if (!a
->machine
&& b
->machine
)
828 if (a
->machine
&& !b
->machine
)
830 if (a
->machine
&& b
->machine
) {
831 o
= strcasecmp(a
->machine
, b
->machine
);
836 o
= strcmp(a
->path
, b
->path
);
838 o
= strcmp(a
->type
, b
->type
);
843 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
844 struct socket_info
*s
;
845 unsigned pathlen
= strlen("LISTEN"),
846 typelen
= strlen("TYPE") * arg_show_types
,
847 socklen
= strlen("UNIT"),
848 servlen
= strlen("ACTIVATES");
849 const char *on
, *off
;
851 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
855 socklen
= MAX(socklen
, strlen(s
->id
));
857 typelen
= MAX(typelen
, strlen(s
->type
));
858 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
860 STRV_FOREACH(a
, s
->triggered
)
861 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
862 servlen
= MAX(servlen
, tmp
);
867 printf("%-*s %-*.*s%-*s %s\n",
869 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
873 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
874 _cleanup_free_
char *j
= NULL
;
879 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
887 printf("%-*s %-*s %-*s",
888 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
891 pathlen
, path
, socklen
, s
->id
);
892 STRV_FOREACH(a
, s
->triggered
)
894 a
== s
->triggered
? "" : ",", *a
);
898 on
= ansi_highlight();
903 on
= ansi_highlight_red();
907 if (!arg_no_legend
) {
908 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
910 printf("Pass --all to see loaded but inactive sockets, too.\n");
916 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
917 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
918 _cleanup_strv_free_
char **machines
= NULL
;
919 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
920 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
922 struct socket_info
*s
;
928 pager_open(arg_no_pager
, false);
930 r
= acquire_bus(BUS_MANAGER
, &bus
);
934 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
938 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
939 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
942 if (!endswith(u
->id
, ".socket"))
945 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
949 c
= get_listening(bus
, u
->unit_path
, &listening
);
955 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
960 for (i
= 0; i
< c
; i
++)
961 socket_infos
[cs
+ i
] = (struct socket_info
) {
962 .machine
= u
->machine
,
964 .type
= listening
[i
*2],
965 .path
= listening
[i
*2 + 1],
966 .triggered
= triggered
,
967 .own_triggered
= i
==0,
970 /* from this point on we will cleanup those socket_infos */
973 listening
= triggered
= NULL
; /* avoid cleanup */
976 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
977 (__compar_fn_t
) socket_info_compare
);
979 output_sockets_list(socket_infos
, cs
);
982 assert(cs
== 0 || socket_infos
);
983 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
986 if (s
->own_triggered
)
987 strv_free(s
->triggered
);
993 static int get_next_elapse(
996 dual_timestamp
*next
) {
998 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1006 r
= sd_bus_get_property_trivial(
1008 "org.freedesktop.systemd1",
1010 "org.freedesktop.systemd1.Timer",
1011 "NextElapseUSecMonotonic",
1016 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1018 r
= sd_bus_get_property_trivial(
1020 "org.freedesktop.systemd1",
1022 "org.freedesktop.systemd1.Timer",
1023 "NextElapseUSecRealtime",
1028 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1034 static int get_last_trigger(
1039 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1046 r
= sd_bus_get_property_trivial(
1048 "org.freedesktop.systemd1",
1050 "org.freedesktop.systemd1.Timer",
1056 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1062 const char* machine
;
1065 usec_t last_trigger
;
1069 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1075 if (!a
->machine
&& b
->machine
)
1077 if (a
->machine
&& !b
->machine
)
1079 if (a
->machine
&& b
->machine
) {
1080 o
= strcasecmp(a
->machine
, b
->machine
);
1085 if (a
->next_elapse
< b
->next_elapse
)
1087 if (a
->next_elapse
> b
->next_elapse
)
1090 return strcmp(a
->id
, b
->id
);
1093 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1094 struct timer_info
*t
;
1096 nextlen
= strlen("NEXT"),
1097 leftlen
= strlen("LEFT"),
1098 lastlen
= strlen("LAST"),
1099 passedlen
= strlen("PASSED"),
1100 unitlen
= strlen("UNIT"),
1101 activatelen
= strlen("ACTIVATES");
1103 const char *on
, *off
;
1105 assert(timer_infos
|| n
== 0);
1107 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1111 if (t
->next_elapse
> 0) {
1112 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1114 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1115 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1117 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1118 leftlen
= MAX(leftlen
, strlen(trel
));
1121 if (t
->last_trigger
> 0) {
1122 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1124 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1125 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1127 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1128 passedlen
= MAX(passedlen
, strlen(trel
));
1131 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1133 STRV_FOREACH(a
, t
->triggered
)
1134 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1136 activatelen
= MAX(activatelen
, ul
);
1141 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1145 passedlen
, "PASSED",
1149 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1150 _cleanup_free_
char *j
= NULL
;
1152 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1153 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1156 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1157 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1159 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1160 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1163 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1170 printf("%-*s %-*s %-*s %-*s %-*s",
1171 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1173 STRV_FOREACH(a
, t
->triggered
)
1175 a
== t
->triggered
? "" : ",", *a
);
1179 on
= ansi_highlight();
1180 off
= ansi_normal();
1184 on
= ansi_highlight_red();
1185 off
= ansi_normal();
1188 if (!arg_no_legend
) {
1189 printf("%s%u timers listed.%s\n", on
, n
, off
);
1191 printf("Pass --all to see loaded but inactive timers, too.\n");
1197 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1203 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1206 if (next
->monotonic
> nw
->monotonic
)
1207 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1209 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1211 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1212 next_elapse
= MIN(converted
, next
->realtime
);
1214 next_elapse
= converted
;
1217 next_elapse
= next
->realtime
;
1222 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1223 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1224 _cleanup_strv_free_
char **machines
= NULL
;
1225 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1226 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1227 struct timer_info
*t
;
1235 pager_open(arg_no_pager
, false);
1237 r
= acquire_bus(BUS_MANAGER
, &bus
);
1241 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1245 dual_timestamp_get(&nw
);
1247 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1248 _cleanup_strv_free_
char **triggered
= NULL
;
1249 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1252 if (!endswith(u
->id
, ".timer"))
1255 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1259 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1263 get_last_trigger(bus
, u
->unit_path
, &last
);
1265 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1270 m
= calc_next_elapse(&nw
, &next
);
1272 timer_infos
[c
++] = (struct timer_info
) {
1273 .machine
= u
->machine
,
1276 .last_trigger
= last
,
1277 .triggered
= triggered
,
1280 triggered
= NULL
; /* avoid cleanup */
1283 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1284 (__compar_fn_t
) timer_info_compare
);
1286 output_timers_list(timer_infos
, c
);
1289 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1290 strv_free(t
->triggered
);
1295 static int compare_unit_file_list(const void *a
, const void *b
) {
1296 const char *d1
, *d2
;
1297 const UnitFileList
*u
= a
, *v
= b
;
1299 d1
= strrchr(u
->path
, '.');
1300 d2
= strrchr(v
->path
, '.');
1305 r
= strcasecmp(d1
, d2
);
1310 return strcasecmp(basename(u
->path
), basename(v
->path
));
1313 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1316 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1319 if (!strv_isempty(arg_types
)) {
1322 dot
= strrchr(u
->path
, '.');
1326 if (!strv_find(arg_types
, dot
+1))
1330 if (!strv_isempty(states
) &&
1331 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1337 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1338 unsigned max_id_len
, id_cols
, state_cols
;
1339 const UnitFileList
*u
;
1341 max_id_len
= strlen("UNIT FILE");
1342 state_cols
= strlen("STATE");
1344 for (u
= units
; u
< units
+ c
; u
++) {
1345 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1346 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1350 unsigned basic_cols
;
1352 id_cols
= MIN(max_id_len
, 25u);
1353 basic_cols
= 1 + id_cols
+ state_cols
;
1354 if (basic_cols
< (unsigned) columns())
1355 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1357 id_cols
= max_id_len
;
1359 if (!arg_no_legend
&& c
> 0)
1360 printf("%-*s %-*s\n",
1361 id_cols
, "UNIT FILE",
1362 state_cols
, "STATE");
1364 for (u
= units
; u
< units
+ c
; u
++) {
1365 _cleanup_free_
char *e
= NULL
;
1366 const char *on
, *off
;
1369 if (IN_SET(u
->state
,
1371 UNIT_FILE_MASKED_RUNTIME
,
1374 on
= ansi_highlight_red();
1375 off
= ansi_normal();
1376 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1377 on
= ansi_highlight_green();
1378 off
= ansi_normal();
1382 id
= basename(u
->path
);
1384 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1386 printf("%-*s %s%-*s%s\n",
1387 id_cols
, e
? e
: id
,
1388 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1392 printf("\n%u unit files listed.\n", c
);
1395 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1396 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1397 _cleanup_free_ UnitFileList
*units
= NULL
;
1404 bool fallback
= false;
1406 pager_open(arg_no_pager
, false);
1408 if (install_client_side()) {
1414 h
= hashmap_new(&string_hash_ops
);
1418 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1420 unit_file_list_free(h
);
1421 return log_error_errno(r
, "Failed to get unit file list: %m");
1424 n_units
= hashmap_size(h
);
1426 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1428 unit_file_list_free(h
);
1432 HASHMAP_FOREACH(u
, h
, i
) {
1433 if (!output_show_unit_file(u
, NULL
, NULL
))
1440 assert(c
<= n_units
);
1445 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1446 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1449 r
= acquire_bus(BUS_MANAGER
, &bus
);
1453 r
= sd_bus_message_new_method_call(
1456 "org.freedesktop.systemd1",
1457 "/org/freedesktop/systemd1",
1458 "org.freedesktop.systemd1.Manager",
1459 "ListUnitFilesByPatterns");
1461 return bus_log_create_error(r
);
1463 r
= sd_bus_message_append_strv(m
, arg_states
);
1465 return bus_log_create_error(r
);
1467 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1469 return bus_log_create_error(r
);
1471 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1472 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1473 /* Fallback to legacy ListUnitFiles method */
1475 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1476 m
= sd_bus_message_unref(m
);
1477 sd_bus_error_free(&error
);
1479 r
= sd_bus_message_new_method_call(
1482 "org.freedesktop.systemd1",
1483 "/org/freedesktop/systemd1",
1484 "org.freedesktop.systemd1.Manager",
1487 return bus_log_create_error(r
);
1489 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1492 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1494 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1496 return bus_log_parse_error(r
);
1498 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1500 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1503 units
[c
] = (struct UnitFileList
) {
1505 unit_file_state_from_string(state
)
1508 if (output_show_unit_file(&units
[c
],
1509 fallback
? arg_states
: NULL
,
1510 fallback
? strv_skip(argv
, 1) : NULL
))
1515 return bus_log_parse_error(r
);
1517 r
= sd_bus_message_exit_container(reply
);
1519 return bus_log_parse_error(r
);
1522 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1523 output_unit_file_list(units
, c
);
1525 if (install_client_side())
1526 for (unit
= units
; unit
< units
+ c
; unit
++)
1532 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1533 _cleanup_free_
char *n
= NULL
;
1534 size_t max_len
= MAX(columns(),20u);
1540 for (i
= level
- 1; i
>= 0; i
--) {
1542 if (len
> max_len
- 3 && !arg_full
) {
1543 printf("%s...\n",max_len
% 2 ? "" : " ");
1546 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1550 if (len
> max_len
- 3 && !arg_full
) {
1551 printf("%s...\n",max_len
% 2 ? "" : " ");
1555 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1559 printf("%s\n", name
);
1563 n
= ellipsize(name
, max_len
-len
, 100);
1571 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1573 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1574 [DEPENDENCY_FORWARD
] = "Requires\0"
1579 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1584 [DEPENDENCY_AFTER
] = "After\0",
1585 [DEPENDENCY_BEFORE
] = "Before\0",
1588 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1589 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1590 _cleanup_strv_free_
char **ret
= NULL
;
1591 _cleanup_free_
char *path
= NULL
;
1597 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1599 path
= unit_dbus_path_from_name(name
);
1603 r
= sd_bus_call_method(
1605 "org.freedesktop.systemd1",
1607 "org.freedesktop.DBus.Properties",
1611 "s", "org.freedesktop.systemd1.Unit");
1613 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1615 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1617 return bus_log_parse_error(r
);
1619 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1622 r
= sd_bus_message_read(reply
, "s", &prop
);
1624 return bus_log_parse_error(r
);
1626 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1627 r
= sd_bus_message_skip(reply
, "v");
1629 return bus_log_parse_error(r
);
1632 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1634 return bus_log_parse_error(r
);
1636 r
= bus_message_read_strv_extend(reply
, &ret
);
1638 return bus_log_parse_error(r
);
1640 r
= sd_bus_message_exit_container(reply
);
1642 return bus_log_parse_error(r
);
1645 r
= sd_bus_message_exit_container(reply
);
1647 return bus_log_parse_error(r
);
1651 return bus_log_parse_error(r
);
1653 r
= sd_bus_message_exit_container(reply
);
1655 return bus_log_parse_error(r
);
1663 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1664 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1666 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1668 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1671 return strcasecmp(*a
, *b
);
1674 static int list_dependencies_one(
1679 unsigned int branches
) {
1681 _cleanup_strv_free_
char **deps
= NULL
;
1689 r
= strv_extend(units
, name
);
1693 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1697 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1699 STRV_FOREACH(c
, deps
) {
1700 if (strv_contains(*units
, *c
)) {
1702 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1712 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1715 (void) get_state_one_unit(bus
, *c
, &active_state
);
1717 switch (active_state
) {
1719 case UNIT_RELOADING
:
1720 case UNIT_ACTIVATING
:
1721 on
= ansi_highlight_green();
1725 case UNIT_DEACTIVATING
:
1730 on
= ansi_highlight_red();
1734 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1737 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1741 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1742 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1749 strv_remove(*units
, name
);
1754 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1755 _cleanup_strv_free_
char **units
= NULL
;
1756 _cleanup_free_
char *unit
= NULL
;
1762 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1764 return log_error_errno(r
, "Failed to mangle unit name: %m");
1768 u
= SPECIAL_DEFAULT_TARGET
;
1770 pager_open(arg_no_pager
, false);
1772 r
= acquire_bus(BUS_MANAGER
, &bus
);
1778 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1781 struct machine_info
{
1785 char *control_group
;
1786 uint32_t n_failed_units
;
1791 static const struct bus_properties_map machine_info_property_map
[] = {
1792 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1793 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1794 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1795 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1796 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1800 static void machine_info_clear(struct machine_info
*info
) {
1804 free(info
->control_group
);
1809 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1815 for (i
= 0; i
< n
; i
++)
1816 machine_info_clear(&machine_infos
[i
]);
1818 free(machine_infos
);
1821 static int compare_machine_info(const void *a
, const void *b
) {
1822 const struct machine_info
*u
= a
, *v
= b
;
1824 if (u
->is_host
!= v
->is_host
)
1825 return u
->is_host
> v
->is_host
? -1 : 1;
1827 return strcasecmp(u
->name
, v
->name
);
1830 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1831 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1837 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1844 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1851 static bool output_show_machine(const char *name
, char **patterns
) {
1852 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1855 static int get_machine_list(
1857 struct machine_info
**_machine_infos
,
1860 struct machine_info
*machine_infos
= NULL
;
1861 _cleanup_strv_free_
char **m
= NULL
;
1862 _cleanup_free_
char *hn
= NULL
;
1867 hn
= gethostname_malloc();
1871 if (output_show_machine(hn
, patterns
)) {
1872 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1875 machine_infos
[c
].is_host
= true;
1876 machine_infos
[c
].name
= hn
;
1879 get_machine_properties(bus
, &machine_infos
[c
]);
1883 r
= sd_get_machine_names(&m
);
1885 return log_error_errno(r
, "Failed to get machine list: %m");
1887 STRV_FOREACH(i
, m
) {
1888 _cleanup_free_
char *class = NULL
;
1890 if (!output_show_machine(*i
, patterns
))
1893 sd_machine_get_class(*i
, &class);
1894 if (!streq_ptr(class, "container"))
1897 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1898 free_machines_list(machine_infos
, c
);
1902 machine_infos
[c
].is_host
= false;
1903 machine_infos
[c
].name
= strdup(*i
);
1904 if (!machine_infos
[c
].name
) {
1905 free_machines_list(machine_infos
, c
);
1909 get_machine_properties(NULL
, &machine_infos
[c
]);
1913 *_machine_infos
= machine_infos
;
1917 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1918 struct machine_info
*m
;
1921 namelen
= sizeof("NAME") - 1,
1922 statelen
= sizeof("STATE") - 1,
1923 failedlen
= sizeof("FAILED") - 1,
1924 jobslen
= sizeof("JOBS") - 1;
1926 assert(machine_infos
|| n
== 0);
1928 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1929 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1930 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1931 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1932 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1934 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1938 if (!arg_no_legend
) {
1942 printf("%-*s %-*s %-*s %-*s\n",
1945 failedlen
, "FAILED",
1949 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1950 const char *on_state
= "", *off_state
= "";
1951 const char *on_failed
= "", *off_failed
= "";
1952 bool circle
= false;
1954 if (streq_ptr(m
->state
, "degraded")) {
1955 on_state
= ansi_highlight_red();
1956 off_state
= ansi_normal();
1958 } else if (!streq_ptr(m
->state
, "running")) {
1959 on_state
= ansi_highlight_yellow();
1960 off_state
= ansi_normal();
1964 if (m
->n_failed_units
> 0) {
1965 on_failed
= ansi_highlight_red();
1966 off_failed
= ansi_normal();
1968 on_failed
= off_failed
= "";
1971 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
1974 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1975 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1976 on_state
, statelen
, strna(m
->state
), off_state
,
1977 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1978 jobslen
, m
->n_jobs
);
1980 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1981 namelen
, strna(m
->name
),
1982 on_state
, statelen
, strna(m
->state
), off_state
,
1983 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1984 jobslen
, m
->n_jobs
);
1988 printf("\n%u machines listed.\n", n
);
1991 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1992 struct machine_info
*machine_infos
= NULL
;
1996 if (geteuid() != 0) {
1997 log_error("Must be root.");
2001 pager_open(arg_no_pager
, false);
2003 r
= acquire_bus(BUS_MANAGER
, &bus
);
2007 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2011 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2012 output_machines_list(machine_infos
, r
);
2013 free_machines_list(machine_infos
, r
);
2018 static int get_default(int argc
, char *argv
[], void *userdata
) {
2019 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2020 _cleanup_free_
char *_path
= NULL
;
2024 if (install_client_side()) {
2025 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2027 return log_error_errno(r
, "Failed to get default target: %m");
2032 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2035 r
= acquire_bus(BUS_MANAGER
, &bus
);
2039 r
= sd_bus_call_method(
2041 "org.freedesktop.systemd1",
2042 "/org/freedesktop/systemd1",
2043 "org.freedesktop.systemd1.Manager",
2049 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2051 r
= sd_bus_message_read(reply
, "s", &path
);
2053 return bus_log_parse_error(r
);
2057 printf("%s\n", path
);
2062 static int set_default(int argc
, char *argv
[], void *userdata
) {
2063 _cleanup_free_
char *unit
= NULL
;
2064 UnitFileChange
*changes
= NULL
;
2065 unsigned n_changes
= 0;
2071 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2073 return log_error_errno(r
, "Failed to mangle unit name: %m");
2075 if (install_client_side()) {
2076 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2077 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2082 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2083 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2086 polkit_agent_open_if_enabled();
2088 r
= acquire_bus(BUS_MANAGER
, &bus
);
2092 r
= sd_bus_call_method(
2094 "org.freedesktop.systemd1",
2095 "/org/freedesktop/systemd1",
2096 "org.freedesktop.systemd1.Manager",
2102 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2104 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2108 /* Try to reload if enabled */
2110 r
= daemon_reload(argc
, argv
, userdata
);
2116 unit_file_changes_free(changes
, n_changes
);
2123 const char *name
, *type
, *state
;
2126 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2127 unsigned id_len
, unit_len
, type_len
, state_len
;
2128 const struct job_info
*j
;
2129 const char *on
, *off
;
2130 bool shorten
= false;
2132 assert(n
== 0 || jobs
);
2135 if (!arg_no_legend
) {
2136 on
= ansi_highlight_green();
2137 off
= ansi_normal();
2139 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2144 pager_open(arg_no_pager
, false);
2146 id_len
= strlen("JOB");
2147 unit_len
= strlen("UNIT");
2148 type_len
= strlen("TYPE");
2149 state_len
= strlen("STATE");
2151 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2152 uint32_t id
= j
->id
;
2153 assert(j
->name
&& j
->type
&& j
->state
);
2155 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2156 unit_len
= MAX(unit_len
, strlen(j
->name
));
2157 type_len
= MAX(type_len
, strlen(j
->type
));
2158 state_len
= MAX(state_len
, strlen(j
->state
));
2161 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2162 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2167 printf("%*s %-*s %-*s %-*s\n",
2171 state_len
, "STATE");
2173 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2174 _cleanup_free_
char *e
= NULL
;
2176 if (streq(j
->state
, "running")) {
2177 on
= ansi_highlight();
2178 off
= ansi_normal();
2182 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2183 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2185 on
, unit_len
, e
? e
: j
->name
, off
,
2187 on
, state_len
, j
->state
, off
);
2190 if (!arg_no_legend
) {
2191 on
= ansi_highlight();
2192 off
= ansi_normal();
2194 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2198 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2199 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2202 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2203 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2204 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2205 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2206 _cleanup_free_
struct job_info
*jobs
= NULL
;
2212 bool skipped
= false;
2214 pager_open(arg_no_pager
, false);
2216 r
= acquire_bus(BUS_MANAGER
, &bus
);
2220 r
= sd_bus_call_method(
2222 "org.freedesktop.systemd1",
2223 "/org/freedesktop/systemd1",
2224 "org.freedesktop.systemd1.Manager",
2230 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2232 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2234 return bus_log_parse_error(r
);
2236 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2237 struct job_info job
= { id
, name
, type
, state
};
2239 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2244 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2250 return bus_log_parse_error(r
);
2252 r
= sd_bus_message_exit_container(reply
);
2254 return bus_log_parse_error(r
);
2256 output_jobs_list(jobs
, c
, skipped
);
2260 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2266 return daemon_reload(argc
, argv
, userdata
);
2268 polkit_agent_open_if_enabled();
2270 r
= acquire_bus(BUS_MANAGER
, &bus
);
2274 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2275 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2279 q
= safe_atou32(*name
, &id
);
2281 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2283 q
= sd_bus_call_method(
2285 "org.freedesktop.systemd1",
2286 "/org/freedesktop/systemd1",
2287 "org.freedesktop.systemd1.Manager",
2293 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2302 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2303 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2307 /* We ignore all errors here, since this is used to show a
2310 /* We don't use unit_dbus_path_from_name() directly since we
2311 * don't want to load the unit if it isn't loaded. */
2313 r
= sd_bus_call_method(
2315 "org.freedesktop.systemd1",
2316 "/org/freedesktop/systemd1",
2317 "org.freedesktop.systemd1.Manager",
2325 r
= sd_bus_message_read(reply
, "o", &path
);
2329 r
= sd_bus_get_property_trivial(
2331 "org.freedesktop.systemd1",
2333 "org.freedesktop.systemd1.Unit",
2343 static void warn_unit_file_changed(const char *name
) {
2346 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2347 ansi_highlight_red(),
2350 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2353 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2360 STRV_FOREACH(p
, lp
->search_path
) {
2361 _cleanup_free_
char *path
;
2363 path
= path_join(arg_root
, *p
, unit_name
);
2367 if (access(path
, F_OK
) == 0) {
2377 static int unit_find_paths(
2379 const char *unit_name
,
2381 char **fragment_path
,
2382 char ***dropin_paths
) {
2384 _cleanup_free_
char *path
= NULL
;
2385 _cleanup_strv_free_
char **dropins
= NULL
;
2389 * Finds where the unit is defined on disk. Returns 0 if the unit
2390 * is not found. Returns 1 if it is found, and sets
2391 * - the path to the unit in *path, if it exists on disk,
2392 * - and a strv of existing drop-ins in *dropins,
2393 * if the arg is not NULL and any dropins were found.
2397 assert(fragment_path
);
2400 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2401 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2402 _cleanup_free_
char *unit
= NULL
;
2404 unit
= unit_dbus_path_from_name(unit_name
);
2408 r
= sd_bus_get_property_string(
2410 "org.freedesktop.systemd1",
2412 "org.freedesktop.systemd1.Unit",
2417 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2420 r
= sd_bus_get_property_strv(
2422 "org.freedesktop.systemd1",
2424 "org.freedesktop.systemd1.Unit",
2429 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2432 _cleanup_set_free_ Set
*names
;
2434 names
= set_new(NULL
);
2438 r
= set_put(names
, unit_name
);
2440 return log_error_errno(r
, "Failed to add unit name: %m");
2442 r
= unit_file_find_path(lp
, unit_name
, &path
);
2447 _cleanup_free_
char *template = NULL
;
2449 r
= unit_name_template(unit_name
, &template);
2450 if (r
< 0 && r
!= -EINVAL
)
2451 return log_error_errno(r
, "Failed to determine template name: %m");
2453 r
= unit_file_find_path(lp
, template, &path
);
2460 r
= unit_file_find_dropin_paths(lp
->search_path
, NULL
, names
, &dropins
);
2468 if (!isempty(path
)) {
2469 *fragment_path
= path
;
2474 if (dropin_paths
&& !strv_isempty(dropins
)) {
2475 *dropin_paths
= dropins
;
2481 log_error("No files found for %s.", unit_name
);
2486 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2487 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2488 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2489 _cleanup_free_
char *buf
= NULL
;
2490 UnitActiveState state
;
2495 assert(active_state
);
2497 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2499 r
= sd_bus_call_method(
2501 "org.freedesktop.systemd1",
2502 "/org/freedesktop/systemd1",
2503 "org.freedesktop.systemd1.Manager",
2509 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2510 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2512 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2513 * considered inactive. */
2514 state
= UNIT_INACTIVE
;
2517 r
= sd_bus_message_read(reply
, "o", &path
);
2519 return bus_log_parse_error(r
);
2521 r
= sd_bus_get_property_string(
2523 "org.freedesktop.systemd1",
2525 "org.freedesktop.systemd1.Unit",
2530 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2532 state
= unit_active_state_from_string(buf
);
2533 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2534 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2539 *active_state
= state
;
2543 static int check_triggering_units(
2547 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2548 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2549 _cleanup_strv_free_
char **triggered_by
= NULL
;
2550 bool print_warning_label
= true;
2551 UnitActiveState active_state
;
2555 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2557 return log_error_errno(r
, "Failed to mangle unit name: %m");
2559 path
= unit_dbus_path_from_name(n
);
2563 r
= sd_bus_get_property_string(
2565 "org.freedesktop.systemd1",
2567 "org.freedesktop.systemd1.Unit",
2572 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2574 if (streq(load_state
, "masked"))
2577 r
= sd_bus_get_property_strv(
2579 "org.freedesktop.systemd1",
2581 "org.freedesktop.systemd1.Unit",
2586 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2588 STRV_FOREACH(i
, triggered_by
) {
2589 r
= get_state_one_unit(bus
, *i
, &active_state
);
2593 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2596 if (print_warning_label
) {
2597 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2598 print_warning_label
= false;
2601 log_warning(" %s", *i
);
2607 static const struct {
2610 } unit_actions
[] = {
2611 { "start", "StartUnit" },
2612 { "stop", "StopUnit" },
2613 { "condstop", "StopUnit" },
2614 { "reload", "ReloadUnit" },
2615 { "restart", "RestartUnit" },
2616 { "try-restart", "TryRestartUnit" },
2617 { "condrestart", "TryRestartUnit" },
2618 { "reload-or-restart", "ReloadOrRestartUnit" },
2619 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2620 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2621 { "condreload", "ReloadOrTryRestartUnit" },
2622 { "force-reload", "ReloadOrTryRestartUnit" }
2625 static const char *verb_to_method(const char *verb
) {
2628 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2629 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2630 return unit_actions
[i
].method
;
2635 static const char *method_to_verb(const char *method
) {
2638 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2639 if (streq_ptr(unit_actions
[i
].method
, method
))
2640 return unit_actions
[i
].verb
;
2645 static int start_unit_one(
2650 sd_bus_error
*error
,
2651 BusWaitForJobs
*w
) {
2653 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2662 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2664 r
= sd_bus_call_method(
2666 "org.freedesktop.systemd1",
2667 "/org/freedesktop/systemd1",
2668 "org.freedesktop.systemd1.Manager",
2676 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2677 /* There's always a fallback possible for
2678 * legacy actions. */
2679 return -EADDRNOTAVAIL
;
2681 verb
= method_to_verb(method
);
2683 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2685 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2686 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2687 log_error("See %s logs and 'systemctl%s status %s' for details.",
2688 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2689 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2695 r
= sd_bus_message_read(reply
, "o", &path
);
2697 return bus_log_parse_error(r
);
2699 if (need_daemon_reload(bus
, name
) > 0)
2700 warn_unit_file_changed(name
);
2703 log_debug("Adding %s to the set", path
);
2704 r
= bus_wait_for_jobs_add(w
, path
);
2712 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2713 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2720 STRV_FOREACH(name
, names
) {
2724 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2726 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2728 return log_error_errno(r
, "Failed to mangle name: %m");
2730 if (string_is_glob(t
))
2731 r
= strv_consume(&globs
, t
);
2733 r
= strv_consume(&mangled
, t
);
2738 /* Query the manager only if any of the names are a glob, since
2739 * this is fairly expensive */
2740 if (!strv_isempty(globs
)) {
2741 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2742 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2743 size_t allocated
, n
;
2745 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2749 n
= strv_length(mangled
);
2752 for (i
= 0; i
< r
; i
++) {
2753 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2756 mangled
[n
] = strdup(unit_infos
[i
].id
);
2760 mangled
[++n
] = NULL
;
2765 mangled
= NULL
; /* do not free */
2770 static const struct {
2774 } action_table
[_ACTION_MAX
] = {
2775 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2776 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2777 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2778 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2779 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2780 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2781 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2782 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2783 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2784 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2785 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2786 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2787 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2788 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2789 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2792 static enum action
verb_to_action(const char *verb
) {
2795 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2796 if (streq_ptr(action_table
[i
].verb
, verb
))
2799 return _ACTION_INVALID
;
2802 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2803 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2804 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2805 _cleanup_strv_free_
char **names
= NULL
;
2810 ask_password_agent_open_if_enabled();
2811 polkit_agent_open_if_enabled();
2813 r
= acquire_bus(BUS_MANAGER
, &bus
);
2817 if (arg_action
== ACTION_SYSTEMCTL
) {
2820 method
= verb_to_method(argv
[0]);
2821 action
= verb_to_action(argv
[0]);
2823 if (streq(argv
[0], "isolate")) {
2827 mode
= action_table
[action
].mode
?: arg_job_mode
;
2829 one_name
= action_table
[action
].target
;
2831 assert(arg_action
< ELEMENTSOF(action_table
));
2832 assert(action_table
[arg_action
].target
);
2834 method
= "StartUnit";
2836 mode
= action_table
[arg_action
].mode
;
2837 one_name
= action_table
[arg_action
].target
;
2841 names
= strv_new(one_name
, NULL
);
2843 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2845 return log_error_errno(r
, "Failed to expand names: %m");
2848 if (!arg_no_block
) {
2849 r
= bus_wait_for_jobs_new(bus
, &w
);
2851 return log_error_errno(r
, "Could not watch jobs: %m");
2854 STRV_FOREACH(name
, names
) {
2855 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2858 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2859 if (r
>= 0 && q
< 0)
2860 r
= translate_bus_error_to_exit_status(q
, &error
);
2863 if (!arg_no_block
) {
2864 int q
, arg_count
= 0;
2865 const char* extra_args
[4] = {};
2867 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2868 extra_args
[arg_count
++] = "--user";
2870 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2871 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2872 extra_args
[arg_count
++] = "-H";
2873 extra_args
[arg_count
++] = arg_host
;
2874 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2875 extra_args
[arg_count
++] = "-M";
2876 extra_args
[arg_count
++] = arg_host
;
2879 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2883 /* When stopping units, warn if they can still be triggered by
2884 * another active unit (socket, path, timer) */
2885 if (!arg_quiet
&& streq(method
, "StopUnit"))
2886 STRV_FOREACH(name
, names
)
2887 check_triggering_units(bus
, *name
);
2893 static int logind_set_wall_message(void) {
2895 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2897 _cleanup_free_
char *m
= NULL
;
2900 r
= acquire_bus(BUS_FULL
, &bus
);
2904 m
= strv_join(arg_wall
, " ");
2908 r
= sd_bus_call_method(
2910 "org.freedesktop.login1",
2911 "/org/freedesktop/login1",
2912 "org.freedesktop.login1.Manager",
2921 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2927 /* Ask systemd-logind, which might grant access to unprivileged users
2928 * through PolicyKit */
2929 static int logind_reboot(enum action a
) {
2931 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2932 const char *method
, *description
;
2936 polkit_agent_open_if_enabled();
2937 (void) logind_set_wall_message();
2939 r
= acquire_bus(BUS_FULL
, &bus
);
2947 description
= "reboot system";
2950 case ACTION_POWEROFF
:
2951 method
= "PowerOff";
2952 description
= "power off system";
2955 case ACTION_SUSPEND
:
2957 description
= "suspend system";
2960 case ACTION_HIBERNATE
:
2961 method
= "Hibernate";
2962 description
= "hibernate system";
2965 case ACTION_HYBRID_SLEEP
:
2966 method
= "HybridSleep";
2967 description
= "put system into hybrid sleep";
2974 r
= sd_bus_call_method(
2976 "org.freedesktop.login1",
2977 "/org/freedesktop/login1",
2978 "org.freedesktop.login1.Manager",
2982 "b", arg_ask_password
);
2984 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2992 static int logind_check_inhibitors(enum action a
) {
2994 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2995 _cleanup_strv_free_
char **sessions
= NULL
;
2996 const char *what
, *who
, *why
, *mode
;
3003 if (arg_ignore_inhibitors
|| arg_force
> 0)
3015 r
= acquire_bus(BUS_FULL
, &bus
);
3019 r
= sd_bus_call_method(
3021 "org.freedesktop.login1",
3022 "/org/freedesktop/login1",
3023 "org.freedesktop.login1.Manager",
3029 /* If logind is not around, then there are no inhibitors... */
3032 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3034 return bus_log_parse_error(r
);
3036 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3037 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3038 _cleanup_strv_free_
char **sv
= NULL
;
3040 if (!streq(mode
, "block"))
3043 sv
= strv_split(what
, ":");
3047 if ((pid_t
) pid
< 0)
3048 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
3050 if (!strv_contains(sv
,
3055 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3058 get_process_comm(pid
, &comm
);
3059 user
= uid_to_name(uid
);
3061 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3062 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3067 return bus_log_parse_error(r
);
3069 r
= sd_bus_message_exit_container(reply
);
3071 return bus_log_parse_error(r
);
3073 /* Check for current sessions */
3074 sd_get_sessions(&sessions
);
3075 STRV_FOREACH(s
, sessions
) {
3076 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3078 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3081 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3084 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3087 sd_session_get_tty(*s
, &tty
);
3088 sd_session_get_seat(*s
, &seat
);
3089 sd_session_get_service(*s
, &service
);
3090 user
= uid_to_name(uid
);
3092 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3099 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3100 action_table
[a
].verb
);
3108 static int logind_prepare_firmware_setup(void) {
3110 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3114 r
= acquire_bus(BUS_FULL
, &bus
);
3118 r
= sd_bus_call_method(
3120 "org.freedesktop.login1",
3121 "/org/freedesktop/login1",
3122 "org.freedesktop.login1.Manager",
3123 "SetRebootToFirmwareSetup",
3128 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3132 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3137 static int prepare_firmware_setup(void) {
3140 if (!arg_firmware_setup
)
3143 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3145 r
= efi_set_reboot_to_firmware(true);
3147 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3152 return logind_prepare_firmware_setup();
3155 static int set_exit_code(uint8_t code
) {
3156 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3160 r
= acquire_bus(BUS_MANAGER
, &bus
);
3164 r
= sd_bus_call_method(
3166 "org.freedesktop.systemd1",
3167 "/org/freedesktop/systemd1",
3168 "org.freedesktop.systemd1.Manager",
3174 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3179 static int start_special(int argc
, char *argv
[], void *userdata
) {
3185 a
= verb_to_action(argv
[0]);
3187 r
= logind_check_inhibitors(a
);
3191 if (arg_force
>= 2 && geteuid() != 0) {
3192 log_error("Must be root.");
3196 r
= prepare_firmware_setup();
3200 if (a
== ACTION_REBOOT
&& argc
> 1) {
3201 r
= update_reboot_parameter_and_warn(argv
[1]);
3205 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3208 /* If the exit code is not given on the command line,
3209 * don't reset it to zero: just keep it as it might
3210 * have been set previously. */
3212 r
= safe_atou8(argv
[1], &code
);
3214 return log_error_errno(r
, "Invalid exit code.");
3216 r
= set_exit_code(code
);
3221 if (arg_force
>= 2 &&
3228 if (arg_force
>= 1 &&
3235 return daemon_reload(argc
, argv
, userdata
);
3237 /* First try logind, to allow authentication with polkit */
3243 ACTION_HYBRID_SLEEP
)) {
3244 r
= logind_reboot(a
);
3247 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3248 /* requested operation is not supported or already in progress */
3251 /* On all other errors, try low-level operation */
3254 return start_unit(argc
, argv
, userdata
);
3257 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3258 _cleanup_strv_free_
char **names
= NULL
;
3259 UnitActiveState active_state
;
3265 r
= acquire_bus(BUS_MANAGER
, &bus
);
3269 r
= expand_names(bus
, args
, NULL
, &names
);
3271 return log_error_errno(r
, "Failed to expand names: %m");
3273 STRV_FOREACH(name
, names
) {
3274 r
= get_state_one_unit(bus
, *name
, &active_state
);
3279 puts(unit_active_state_to_string(active_state
));
3281 for (i
= 0; i
< nb_states
; ++i
)
3282 if (good_states
[i
] == active_state
)
3286 /* use the given return code for the case that we won't find
3287 * any unit which matches the list */
3288 return found
? 0 : code
;
3291 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3292 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3293 /* According to LSB: 3, "program is not running" */
3294 return check_unit_generic(3, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3297 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3298 const UnitActiveState states
[] = { UNIT_FAILED
};
3299 return check_unit_generic(1, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3302 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3303 _cleanup_strv_free_
char **names
= NULL
;
3304 char *kill_who
= NULL
, **name
;
3308 polkit_agent_open_if_enabled();
3310 r
= acquire_bus(BUS_MANAGER
, &bus
);
3315 arg_kill_who
= "all";
3317 /* --fail was specified */
3318 if (streq(arg_job_mode
, "fail"))
3319 kill_who
= strjoina(arg_kill_who
, "-fail");
3321 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3323 return log_error_errno(r
, "Failed to expand names: %m");
3325 STRV_FOREACH(name
, names
) {
3326 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3328 q
= sd_bus_call_method(
3330 "org.freedesktop.systemd1",
3331 "/org/freedesktop/systemd1",
3332 "org.freedesktop.systemd1.Manager",
3336 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3338 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3347 typedef struct ExecStatusInfo
{
3355 usec_t start_timestamp
;
3356 usec_t exit_timestamp
;
3361 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3364 static void exec_status_info_free(ExecStatusInfo
*i
) {
3373 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3374 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3377 int32_t code
, status
;
3383 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3385 return bus_log_parse_error(r
);
3389 r
= sd_bus_message_read(m
, "s", &path
);
3391 return bus_log_parse_error(r
);
3393 i
->path
= strdup(path
);
3397 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3399 return bus_log_parse_error(r
);
3401 r
= sd_bus_message_read(m
,
3404 &start_timestamp
, &start_timestamp_monotonic
,
3405 &exit_timestamp
, &exit_timestamp_monotonic
,
3409 return bus_log_parse_error(r
);
3412 i
->start_timestamp
= (usec_t
) start_timestamp
;
3413 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3414 i
->pid
= (pid_t
) pid
;
3418 r
= sd_bus_message_exit_container(m
);
3420 return bus_log_parse_error(r
);
3425 typedef struct UnitStatusInfo
{
3427 const char *load_state
;
3428 const char *active_state
;
3429 const char *sub_state
;
3430 const char *unit_file_state
;
3431 const char *unit_file_preset
;
3433 const char *description
;
3434 const char *following
;
3436 char **documentation
;
3438 const char *fragment_path
;
3439 const char *source_path
;
3440 const char *control_group
;
3442 char **dropin_paths
;
3444 const char *load_error
;
3447 usec_t inactive_exit_timestamp
;
3448 usec_t inactive_exit_timestamp_monotonic
;
3449 usec_t active_enter_timestamp
;
3450 usec_t active_exit_timestamp
;
3451 usec_t inactive_enter_timestamp
;
3453 bool need_daemon_reload
;
3459 const char *status_text
;
3460 const char *pid_file
;
3464 usec_t start_timestamp
;
3465 usec_t exit_timestamp
;
3467 int exit_code
, exit_status
;
3469 usec_t condition_timestamp
;
3470 bool condition_result
;
3471 bool failed_condition_trigger
;
3472 bool failed_condition_negate
;
3473 const char *failed_condition
;
3474 const char *failed_condition_parameter
;
3476 usec_t assert_timestamp
;
3478 bool failed_assert_trigger
;
3479 bool failed_assert_negate
;
3480 const char *failed_assert
;
3481 const char *failed_assert_parameter
;
3484 unsigned n_accepted
;
3485 unsigned n_connections
;
3488 /* Pairs of type, path */
3492 const char *sysfs_path
;
3494 /* Mount, Automount */
3501 uint64_t memory_current
;
3502 uint64_t memory_limit
;
3503 uint64_t cpu_usage_nsec
;
3504 uint64_t tasks_current
;
3507 LIST_HEAD(ExecStatusInfo
, exec
);
3510 static void print_status_info(
3516 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3518 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3519 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3526 /* This shows pretty information about a unit. See
3527 * print_property() for a low-level property printer */
3529 if (streq_ptr(i
->active_state
, "failed")) {
3530 active_on
= ansi_highlight_red();
3531 active_off
= ansi_normal();
3532 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3533 active_on
= ansi_highlight_green();
3534 active_off
= ansi_normal();
3536 active_on
= active_off
= "";
3538 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3540 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3541 printf(" - %s", i
->description
);
3546 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3548 if (streq_ptr(i
->load_state
, "error")) {
3549 on
= ansi_highlight_red();
3550 off
= ansi_normal();
3554 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3556 if (i
->load_error
!= 0)
3557 printf(" Loaded: %s%s%s (Reason: %s)\n",
3558 on
, strna(i
->load_state
), off
, i
->load_error
);
3559 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3560 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3561 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3562 else if (path
&& !isempty(i
->unit_file_state
))
3563 printf(" Loaded: %s%s%s (%s; %s)\n",
3564 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3566 printf(" Loaded: %s%s%s (%s)\n",
3567 on
, strna(i
->load_state
), off
, path
);
3569 printf(" Loaded: %s%s%s\n",
3570 on
, strna(i
->load_state
), off
);
3573 printf("Transient: yes\n");
3575 if (!strv_isempty(i
->dropin_paths
)) {
3576 _cleanup_free_
char *dir
= NULL
;
3580 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3581 if (! dir
|| last
) {
3582 printf(dir
? " " : " Drop-In: ");
3586 dir
= dirname_malloc(*dropin
);
3592 printf("%s\n %s", dir
,
3593 special_glyph(TREE_RIGHT
));
3596 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3598 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3602 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3604 printf(" Active: %s%s (%s)%s",
3605 active_on
, strna(i
->active_state
), ss
, active_off
);
3607 printf(" Active: %s%s%s",
3608 active_on
, strna(i
->active_state
), active_off
);
3610 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3611 printf(" (Result: %s)", i
->result
);
3613 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3614 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3615 (streq_ptr(i
->active_state
, "inactive") ||
3616 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3617 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3618 i
->active_exit_timestamp
;
3620 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3621 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3624 printf(" since %s; %s\n", s2
, s1
);
3626 printf(" since %s\n", s2
);
3630 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3631 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3632 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3634 printf("Condition: start %scondition failed%s at %s%s%s\n",
3635 ansi_highlight_yellow(), ansi_normal(),
3636 s2
, s1
? "; " : "", strempty(s1
));
3637 if (i
->failed_condition_trigger
)
3638 printf(" none of the trigger conditions were met\n");
3639 else if (i
->failed_condition
)
3640 printf(" %s=%s%s was not met\n",
3641 i
->failed_condition
,
3642 i
->failed_condition_negate
? "!" : "",
3643 i
->failed_condition_parameter
);
3646 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3647 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3648 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3650 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3651 ansi_highlight_red(), ansi_normal(),
3652 s2
, s1
? "; " : "", strempty(s1
));
3653 if (i
->failed_assert_trigger
)
3654 printf(" none of the trigger assertions were met\n");
3655 else if (i
->failed_assert
)
3656 printf(" %s=%s%s was not met\n",
3658 i
->failed_assert_negate
? "!" : "",
3659 i
->failed_assert_parameter
);
3663 printf(" Device: %s\n", i
->sysfs_path
);
3665 printf(" Where: %s\n", i
->where
);
3667 printf(" What: %s\n", i
->what
);
3669 STRV_FOREACH(t
, i
->documentation
)
3670 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3672 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3673 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3676 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3678 LIST_FOREACH(exec
, p
, i
->exec
) {
3679 _cleanup_free_
char *argv
= NULL
;
3682 /* Only show exited processes here */
3686 argv
= strv_join(p
->argv
, " ");
3687 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3689 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3691 on
= ansi_highlight_red();
3692 off
= ansi_normal();
3696 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3698 if (p
->code
== CLD_EXITED
) {
3701 printf("status=%i", p
->status
);
3703 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3708 printf("signal=%s", signal_to_string(p
->status
));
3710 printf(")%s\n", off
);
3712 if (i
->main_pid
== p
->pid
&&
3713 i
->start_timestamp
== p
->start_timestamp
&&
3714 i
->exit_timestamp
== p
->start_timestamp
)
3715 /* Let's not show this twice */
3718 if (p
->pid
== i
->control_pid
)
3722 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3723 if (i
->main_pid
> 0) {
3724 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3727 _cleanup_free_
char *comm
= NULL
;
3728 get_process_comm(i
->main_pid
, &comm
);
3730 printf(" (%s)", comm
);
3731 } else if (i
->exit_code
> 0) {
3732 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3734 if (i
->exit_code
== CLD_EXITED
) {
3737 printf("status=%i", i
->exit_status
);
3739 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3744 printf("signal=%s", signal_to_string(i
->exit_status
));
3748 if (i
->control_pid
> 0)
3752 if (i
->control_pid
> 0) {
3753 _cleanup_free_
char *c
= NULL
;
3755 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3757 get_process_comm(i
->control_pid
, &c
);
3766 printf(" Status: \"%s\"\n", i
->status_text
);
3767 if (i
->status_errno
> 0)
3768 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3770 if (i
->tasks_current
!= (uint64_t) -1) {
3771 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3773 if (i
->tasks_max
!= (uint64_t) -1)
3774 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3779 if (i
->memory_current
!= (uint64_t) -1) {
3780 char buf
[FORMAT_BYTES_MAX
];
3782 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3784 if (i
->memory_limit
!= (uint64_t) -1)
3785 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3790 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3791 char buf
[FORMAT_TIMESPAN_MAX
];
3792 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3795 if (i
->control_group
)
3796 printf(" CGroup: %s\n", i
->control_group
);
3799 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3800 static const char prefix
[] = " ";
3804 if (c
> sizeof(prefix
) - 1)
3805 c
-= sizeof(prefix
) - 1;
3809 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
3814 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
3816 if (i
->main_pid
> 0)
3817 extra
[k
++] = i
->main_pid
;
3819 if (i
->control_pid
> 0)
3820 extra
[k
++] = i
->control_pid
;
3822 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
3824 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
3827 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3828 show_journal_by_unit(
3833 i
->inactive_exit_timestamp_monotonic
,
3836 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3837 SD_JOURNAL_LOCAL_ONLY
,
3838 arg_scope
== UNIT_FILE_SYSTEM
,
3841 if (i
->need_daemon_reload
)
3842 warn_unit_file_changed(i
->id
);
3845 static void show_unit_help(UnitStatusInfo
*i
) {
3850 if (!i
->documentation
) {
3851 log_info("Documentation for %s not known.", i
->id
);
3855 STRV_FOREACH(p
, i
->documentation
)
3856 if (startswith(*p
, "man:"))
3857 show_man_page(*p
+ 4, false);
3859 log_info("Can't show: %s", *p
);
3862 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3869 switch (contents
[0]) {
3871 case SD_BUS_TYPE_STRING
: {
3874 r
= sd_bus_message_read(m
, "s", &s
);
3876 return bus_log_parse_error(r
);
3879 if (streq(name
, "Id"))
3881 else if (streq(name
, "LoadState"))
3883 else if (streq(name
, "ActiveState"))
3884 i
->active_state
= s
;
3885 else if (streq(name
, "SubState"))
3887 else if (streq(name
, "Description"))
3889 else if (streq(name
, "FragmentPath"))
3890 i
->fragment_path
= s
;
3891 else if (streq(name
, "SourcePath"))
3894 else if (streq(name
, "DefaultControlGroup")) {
3896 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3898 i
->control_group
= e
;
3901 else if (streq(name
, "ControlGroup"))
3902 i
->control_group
= s
;
3903 else if (streq(name
, "StatusText"))
3905 else if (streq(name
, "PIDFile"))
3907 else if (streq(name
, "SysFSPath"))
3909 else if (streq(name
, "Where"))
3911 else if (streq(name
, "What"))
3913 else if (streq(name
, "Following"))
3915 else if (streq(name
, "UnitFileState"))
3916 i
->unit_file_state
= s
;
3917 else if (streq(name
, "UnitFilePreset"))
3918 i
->unit_file_preset
= s
;
3919 else if (streq(name
, "Result"))
3926 case SD_BUS_TYPE_BOOLEAN
: {
3929 r
= sd_bus_message_read(m
, "b", &b
);
3931 return bus_log_parse_error(r
);
3933 if (streq(name
, "Accept"))
3935 else if (streq(name
, "NeedDaemonReload"))
3936 i
->need_daemon_reload
= b
;
3937 else if (streq(name
, "ConditionResult"))
3938 i
->condition_result
= b
;
3939 else if (streq(name
, "AssertResult"))
3940 i
->assert_result
= b
;
3941 else if (streq(name
, "Transient"))
3947 case SD_BUS_TYPE_UINT32
: {
3950 r
= sd_bus_message_read(m
, "u", &u
);
3952 return bus_log_parse_error(r
);
3954 if (streq(name
, "MainPID")) {
3956 i
->main_pid
= (pid_t
) u
;
3959 } else if (streq(name
, "ControlPID"))
3960 i
->control_pid
= (pid_t
) u
;
3961 else if (streq(name
, "ExecMainPID")) {
3963 i
->main_pid
= (pid_t
) u
;
3964 } else if (streq(name
, "NAccepted"))
3966 else if (streq(name
, "NConnections"))
3967 i
->n_connections
= u
;
3972 case SD_BUS_TYPE_INT32
: {
3975 r
= sd_bus_message_read(m
, "i", &j
);
3977 return bus_log_parse_error(r
);
3979 if (streq(name
, "ExecMainCode"))
3980 i
->exit_code
= (int) j
;
3981 else if (streq(name
, "ExecMainStatus"))
3982 i
->exit_status
= (int) j
;
3983 else if (streq(name
, "StatusErrno"))
3984 i
->status_errno
= (int) j
;
3989 case SD_BUS_TYPE_UINT64
: {
3992 r
= sd_bus_message_read(m
, "t", &u
);
3994 return bus_log_parse_error(r
);
3996 if (streq(name
, "ExecMainStartTimestamp"))
3997 i
->start_timestamp
= (usec_t
) u
;
3998 else if (streq(name
, "ExecMainExitTimestamp"))
3999 i
->exit_timestamp
= (usec_t
) u
;
4000 else if (streq(name
, "ActiveEnterTimestamp"))
4001 i
->active_enter_timestamp
= (usec_t
) u
;
4002 else if (streq(name
, "InactiveEnterTimestamp"))
4003 i
->inactive_enter_timestamp
= (usec_t
) u
;
4004 else if (streq(name
, "InactiveExitTimestamp"))
4005 i
->inactive_exit_timestamp
= (usec_t
) u
;
4006 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4007 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4008 else if (streq(name
, "ActiveExitTimestamp"))
4009 i
->active_exit_timestamp
= (usec_t
) u
;
4010 else if (streq(name
, "ConditionTimestamp"))
4011 i
->condition_timestamp
= (usec_t
) u
;
4012 else if (streq(name
, "AssertTimestamp"))
4013 i
->assert_timestamp
= (usec_t
) u
;
4014 else if (streq(name
, "MemoryCurrent"))
4015 i
->memory_current
= u
;
4016 else if (streq(name
, "MemoryLimit"))
4017 i
->memory_limit
= u
;
4018 else if (streq(name
, "TasksCurrent"))
4019 i
->tasks_current
= u
;
4020 else if (streq(name
, "TasksMax"))
4022 else if (streq(name
, "CPUUsageNSec"))
4023 i
->cpu_usage_nsec
= u
;
4028 case SD_BUS_TYPE_ARRAY
:
4030 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4031 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4033 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4035 return bus_log_parse_error(r
);
4037 info
= new0(ExecStatusInfo
, 1);
4041 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4043 info
->name
= strdup(name
);
4047 LIST_PREPEND(exec
, i
->exec
, info
);
4049 info
= new0(ExecStatusInfo
, 1);
4055 return bus_log_parse_error(r
);
4057 r
= sd_bus_message_exit_container(m
);
4059 return bus_log_parse_error(r
);
4063 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4064 const char *type
, *path
;
4066 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4068 return bus_log_parse_error(r
);
4070 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4072 r
= strv_extend(&i
->listen
, type
);
4076 r
= strv_extend(&i
->listen
, path
);
4081 return bus_log_parse_error(r
);
4083 r
= sd_bus_message_exit_container(m
);
4085 return bus_log_parse_error(r
);
4089 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4091 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4093 return bus_log_parse_error(r
);
4095 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4097 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4099 return bus_log_parse_error(r
);
4101 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4102 const char *cond
, *param
;
4103 int trigger
, negate
;
4106 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4108 return bus_log_parse_error(r
);
4110 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4111 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4112 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4113 i
->failed_condition
= cond
;
4114 i
->failed_condition_trigger
= trigger
;
4115 i
->failed_condition_negate
= negate
;
4116 i
->failed_condition_parameter
= param
;
4120 return bus_log_parse_error(r
);
4122 r
= sd_bus_message_exit_container(m
);
4124 return bus_log_parse_error(r
);
4126 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4127 const char *cond
, *param
;
4128 int trigger
, negate
;
4131 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4133 return bus_log_parse_error(r
);
4135 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4136 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4137 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4138 i
->failed_assert
= cond
;
4139 i
->failed_assert_trigger
= trigger
;
4140 i
->failed_assert_negate
= negate
;
4141 i
->failed_assert_parameter
= param
;
4145 return bus_log_parse_error(r
);
4147 r
= sd_bus_message_exit_container(m
);
4149 return bus_log_parse_error(r
);
4156 case SD_BUS_TYPE_STRUCT_BEGIN
:
4158 if (streq(name
, "LoadError")) {
4159 const char *n
, *message
;
4161 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4163 return bus_log_parse_error(r
);
4165 if (!isempty(message
))
4166 i
->load_error
= message
;
4179 r
= sd_bus_message_skip(m
, contents
);
4181 return bus_log_parse_error(r
);
4186 #define print_prop(name, fmt, ...) \
4189 printf(fmt "\n", __VA_ARGS__); \
4191 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4194 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4200 /* This is a low-level property printer, see
4201 * print_status_info() for the nicer output */
4203 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4204 /* skip what we didn't read */
4205 r
= sd_bus_message_skip(m
, contents
);
4209 switch (contents
[0]) {
4211 case SD_BUS_TYPE_STRUCT_BEGIN
:
4213 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4216 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4218 return bus_log_parse_error(r
);
4221 print_prop(name
, "%"PRIu32
, u
);
4223 print_prop(name
, "%s", "");
4227 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4230 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4232 return bus_log_parse_error(r
);
4234 if (arg_all
|| !isempty(s
))
4235 print_prop(name
, "%s", s
);
4239 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4240 const char *a
= NULL
, *b
= NULL
;
4242 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4244 return bus_log_parse_error(r
);
4246 if (arg_all
|| !isempty(a
) || !isempty(b
))
4247 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4250 } else if (streq_ptr(name
, "SystemCallFilter")) {
4251 _cleanup_strv_free_
char **l
= NULL
;
4254 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4256 return bus_log_parse_error(r
);
4258 r
= sd_bus_message_read(m
, "b", &whitelist
);
4260 return bus_log_parse_error(r
);
4262 r
= sd_bus_message_read_strv(m
, &l
);
4264 return bus_log_parse_error(r
);
4266 r
= sd_bus_message_exit_container(m
);
4268 return bus_log_parse_error(r
);
4270 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4275 fputs(name
, stdout
);
4282 STRV_FOREACH(i
, l
) {
4290 fputc('\n', stdout
);
4298 case SD_BUS_TYPE_ARRAY
:
4300 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4304 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4306 return bus_log_parse_error(r
);
4308 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4309 print_prop("EnvironmentFile", "%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4312 return bus_log_parse_error(r
);
4314 r
= sd_bus_message_exit_container(m
);
4316 return bus_log_parse_error(r
);
4320 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4321 const char *type
, *path
;
4323 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4325 return bus_log_parse_error(r
);
4327 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4328 print_prop(type
, "%s", path
);
4330 return bus_log_parse_error(r
);
4332 r
= sd_bus_message_exit_container(m
);
4334 return bus_log_parse_error(r
);
4338 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4339 const char *type
, *path
;
4341 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4343 return bus_log_parse_error(r
);
4345 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4349 printf("Listen%s=%s\n", type
, path
);
4351 return bus_log_parse_error(r
);
4353 r
= sd_bus_message_exit_container(m
);
4355 return bus_log_parse_error(r
);
4359 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4361 uint64_t value
, next_elapse
;
4363 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4365 return bus_log_parse_error(r
);
4367 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4368 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4370 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4371 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4372 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4375 return bus_log_parse_error(r
);
4377 r
= sd_bus_message_exit_container(m
);
4379 return bus_log_parse_error(r
);
4383 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4384 ExecStatusInfo info
= {};
4386 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4388 return bus_log_parse_error(r
);
4390 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4391 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4392 _cleanup_free_
char *tt
;
4394 tt
= strv_join(info
.argv
, " ");
4397 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4400 yes_no(info
.ignore
),
4401 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4402 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4404 sigchld_code_to_string(info
.code
),
4406 info
.code
== CLD_EXITED
? "" : "/",
4407 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4410 strv_free(info
.argv
);
4414 r
= sd_bus_message_exit_container(m
);
4416 return bus_log_parse_error(r
);
4420 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4421 const char *path
, *rwm
;
4423 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4425 return bus_log_parse_error(r
);
4427 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4428 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4430 return bus_log_parse_error(r
);
4432 r
= sd_bus_message_exit_container(m
);
4434 return bus_log_parse_error(r
);
4438 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "IODeviceWeight") || streq(name
, "BlockIODeviceWeight"))) {
4442 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4444 return bus_log_parse_error(r
);
4446 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4447 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4449 return bus_log_parse_error(r
);
4451 r
= sd_bus_message_exit_container(m
);
4453 return bus_log_parse_error(r
);
4457 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (cgroup_io_limit_type_from_string(name
) >= 0 ||
4458 streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4462 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4464 return bus_log_parse_error(r
);
4466 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4467 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4469 return bus_log_parse_error(r
);
4471 r
= sd_bus_message_exit_container(m
);
4473 return bus_log_parse_error(r
);
4481 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4483 return bus_log_parse_error(r
);
4486 r
= sd_bus_message_skip(m
, contents
);
4488 return bus_log_parse_error(r
);
4491 printf("%s=[unprintable]\n", name
);
4497 static int show_one(
4501 bool show_properties
,
4505 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4506 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4507 UnitStatusInfo info
= {
4508 .memory_current
= (uint64_t) -1,
4509 .memory_limit
= (uint64_t) -1,
4510 .cpu_usage_nsec
= (uint64_t) -1,
4511 .tasks_current
= (uint64_t) -1,
4512 .tasks_max
= (uint64_t) -1,
4520 log_debug("Showing one %s", path
);
4522 r
= sd_bus_call_method(
4524 "org.freedesktop.systemd1",
4526 "org.freedesktop.DBus.Properties",
4532 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4534 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4536 return bus_log_parse_error(r
);
4543 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4544 const char *name
, *contents
;
4546 r
= sd_bus_message_read(reply
, "s", &name
);
4548 return bus_log_parse_error(r
);
4550 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4552 return bus_log_parse_error(r
);
4554 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4556 return bus_log_parse_error(r
);
4558 if (show_properties
)
4559 r
= print_property(name
, reply
, contents
);
4561 r
= status_property(name
, reply
, &info
, contents
);
4565 r
= sd_bus_message_exit_container(reply
);
4567 return bus_log_parse_error(r
);
4569 r
= sd_bus_message_exit_container(reply
);
4571 return bus_log_parse_error(r
);
4574 return bus_log_parse_error(r
);
4576 r
= sd_bus_message_exit_container(reply
);
4578 return bus_log_parse_error(r
);
4582 if (!show_properties
) {
4583 if (streq(verb
, "help"))
4584 show_unit_help(&info
);
4586 print_status_info(bus
, &info
, ellipsized
);
4589 strv_free(info
.documentation
);
4590 strv_free(info
.dropin_paths
);
4591 strv_free(info
.listen
);
4593 if (!streq_ptr(info
.active_state
, "active") &&
4594 !streq_ptr(info
.active_state
, "reloading") &&
4595 streq(verb
, "status")) {
4596 /* According to LSB: "program not running" */
4597 /* 0: program is running or service is OK
4598 * 1: program is dead and /run PID file exists
4599 * 2: program is dead and /run/lock lock file exists
4600 * 3: program is not running
4601 * 4: program or service status is unknown
4603 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4609 while ((p
= info
.exec
)) {
4610 LIST_REMOVE(exec
, info
.exec
, p
);
4611 exec_status_info_free(p
);
4617 static int get_unit_dbus_path_by_pid(
4622 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4623 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4627 r
= sd_bus_call_method(
4629 "org.freedesktop.systemd1",
4630 "/org/freedesktop/systemd1",
4631 "org.freedesktop.systemd1.Manager",
4637 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4639 r
= sd_bus_message_read(reply
, "o", &u
);
4641 return bus_log_parse_error(r
);
4651 static int show_all(
4654 bool show_properties
,
4658 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4659 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4664 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4668 pager_open(arg_no_pager
, false);
4672 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4674 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4675 _cleanup_free_
char *p
= NULL
;
4677 p
= unit_dbus_path_from_name(u
->id
);
4681 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4684 else if (r
> 0 && ret
== 0)
4691 static int show_system_status(sd_bus
*bus
) {
4692 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4693 _cleanup_free_
char *hn
= NULL
;
4694 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4695 const char *on
, *off
;
4698 hn
= gethostname_malloc();
4702 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4704 return log_error_errno(r
, "Failed to read server status: %m");
4706 if (streq_ptr(mi
.state
, "degraded")) {
4707 on
= ansi_highlight_red();
4708 off
= ansi_normal();
4709 } else if (!streq_ptr(mi
.state
, "running")) {
4710 on
= ansi_highlight_yellow();
4711 off
= ansi_normal();
4715 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4717 printf(" State: %s%s%s\n",
4718 on
, strna(mi
.state
), off
);
4720 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
4721 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
4723 printf(" Since: %s; %s\n",
4724 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4725 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4727 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4728 if (IN_SET(arg_transport
,
4729 BUS_TRANSPORT_LOCAL
,
4730 BUS_TRANSPORT_MACHINE
)) {
4731 static const char prefix
[] = " ";
4735 if (c
> sizeof(prefix
) - 1)
4736 c
-= sizeof(prefix
) - 1;
4740 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
4746 static int show(int argc
, char *argv
[], void *userdata
) {
4747 bool show_properties
, show_status
, show_help
, new_line
= false;
4748 bool ellipsized
= false;
4754 show_properties
= streq(argv
[0], "show");
4755 show_status
= streq(argv
[0], "status");
4756 show_help
= streq(argv
[0], "help");
4758 if (show_help
&& argc
<= 1) {
4759 log_error("This command expects one or more unit names. Did you mean --help?");
4763 pager_open(arg_no_pager
, false);
4766 /* Increase max number of open files to 16K if we can, we
4767 * might needs this when browsing journal files, which might
4768 * be split up into many files. */
4769 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4771 r
= acquire_bus(BUS_MANAGER
, &bus
);
4775 /* If no argument is specified inspect the manager itself */
4776 if (show_properties
&& argc
<= 1)
4777 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4779 if (show_status
&& argc
<= 1) {
4781 pager_open(arg_no_pager
, false);
4782 show_system_status(bus
);
4786 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4788 _cleanup_free_
char **patterns
= NULL
;
4791 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4792 _cleanup_free_
char *unit
= NULL
;
4795 if (safe_atou32(*name
, &id
) < 0) {
4796 if (strv_push(&patterns
, *name
) < 0)
4800 } else if (show_properties
) {
4801 /* Interpret as job id */
4802 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4806 /* Interpret as PID */
4807 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4814 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4817 else if (r
> 0 && ret
== 0)
4821 if (!strv_isempty(patterns
)) {
4822 _cleanup_strv_free_
char **names
= NULL
;
4824 r
= expand_names(bus
, patterns
, NULL
, &names
);
4826 return log_error_errno(r
, "Failed to expand names: %m");
4828 STRV_FOREACH(name
, names
) {
4829 _cleanup_free_
char *unit
;
4831 unit
= unit_dbus_path_from_name(*name
);
4835 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4838 else if (r
> 0 && ret
== 0)
4844 if (ellipsized
&& !arg_quiet
)
4845 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4850 static int cat_file(const char *filename
, bool newline
) {
4851 _cleanup_close_
int fd
;
4853 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4857 printf("%s%s# %s%s\n",
4858 newline
? "\n" : "",
4859 ansi_highlight_blue(),
4864 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4867 static int cat(int argc
, char *argv
[], void *userdata
) {
4868 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4869 _cleanup_strv_free_
char **names
= NULL
;
4875 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4876 log_error("Cannot remotely cat units.");
4880 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
4882 return log_error_errno(r
, "Failed to determine unit paths: %m");
4884 r
= acquire_bus(BUS_MANAGER
, &bus
);
4888 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4890 return log_error_errno(r
, "Failed to expand names: %m");
4892 pager_open(arg_no_pager
, false);
4894 STRV_FOREACH(name
, names
) {
4895 _cleanup_free_
char *fragment_path
= NULL
;
4896 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4899 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4910 if (fragment_path
) {
4911 r
= cat_file(fragment_path
, false);
4913 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4916 STRV_FOREACH(path
, dropin_paths
) {
4917 r
= cat_file(*path
, path
== dropin_paths
);
4919 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4926 static int set_property(int argc
, char *argv
[], void *userdata
) {
4927 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4928 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4929 _cleanup_free_
char *n
= NULL
;
4934 polkit_agent_open_if_enabled();
4936 r
= acquire_bus(BUS_MANAGER
, &bus
);
4940 r
= sd_bus_message_new_method_call(
4943 "org.freedesktop.systemd1",
4944 "/org/freedesktop/systemd1",
4945 "org.freedesktop.systemd1.Manager",
4946 "SetUnitProperties");
4948 return bus_log_create_error(r
);
4950 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4952 return log_error_errno(r
, "Failed to mangle unit name: %m");
4954 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4956 return bus_log_create_error(r
);
4958 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4960 return bus_log_create_error(r
);
4962 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4963 r
= bus_append_unit_property_assignment(m
, *i
);
4968 r
= sd_bus_message_close_container(m
);
4970 return bus_log_create_error(r
);
4972 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4974 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4979 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4980 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4985 polkit_agent_open_if_enabled();
4987 r
= acquire_bus(BUS_MANAGER
, &bus
);
4991 if (arg_action
== ACTION_RELOAD
)
4993 else if (arg_action
== ACTION_REEXEC
)
4994 method
= "Reexecute";
4996 assert(arg_action
== ACTION_SYSTEMCTL
);
4999 streq(argv
[0], "clear-jobs") ||
5000 streq(argv
[0], "cancel") ? "ClearJobs" :
5001 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5002 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5003 streq(argv
[0], "halt") ? "Halt" :
5004 streq(argv
[0], "poweroff") ? "PowerOff" :
5005 streq(argv
[0], "reboot") ? "Reboot" :
5006 streq(argv
[0], "kexec") ? "KExec" :
5007 streq(argv
[0], "exit") ? "Exit" :
5008 /* "daemon-reload" */ "Reload";
5011 r
= sd_bus_call_method(
5013 "org.freedesktop.systemd1",
5014 "/org/freedesktop/systemd1",
5015 "org.freedesktop.systemd1.Manager",
5020 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
5021 /* There's always a fallback possible for
5022 * legacy actions. */
5024 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
5025 /* On reexecution, we expect a disconnect, not a
5029 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5031 return r
< 0 ? r
: 0;
5034 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5035 _cleanup_strv_free_
char **names
= NULL
;
5041 return daemon_reload(argc
, argv
, userdata
);
5043 polkit_agent_open_if_enabled();
5045 r
= acquire_bus(BUS_MANAGER
, &bus
);
5049 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5051 return log_error_errno(r
, "Failed to expand names: %m");
5053 STRV_FOREACH(name
, names
) {
5054 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5056 q
= sd_bus_call_method(
5058 "org.freedesktop.systemd1",
5059 "/org/freedesktop/systemd1",
5060 "org.freedesktop.systemd1.Manager",
5066 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5075 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5076 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5077 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5082 pager_open(arg_no_pager
, false);
5084 r
= acquire_bus(BUS_MANAGER
, &bus
);
5088 r
= sd_bus_get_property(
5090 "org.freedesktop.systemd1",
5091 "/org/freedesktop/systemd1",
5092 "org.freedesktop.systemd1.Manager",
5098 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5100 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5102 return bus_log_parse_error(r
);
5104 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5107 return bus_log_parse_error(r
);
5109 r
= sd_bus_message_exit_container(reply
);
5111 return bus_log_parse_error(r
);
5116 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5117 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5118 _cleanup_free_
char *cmdline_init
= NULL
;
5119 const char *root
, *init
;
5123 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5124 log_error("Cannot switch root remotely.");
5128 if (argc
< 2 || argc
> 3) {
5129 log_error("Wrong number of arguments.");
5138 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5139 "init", &cmdline_init
,
5142 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5144 init
= cmdline_init
;
5151 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5153 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5154 root_init_path
= strjoina(root
, "/", init
);
5156 /* If the passed init is actually the same as the
5157 * systemd binary, then let's suppress it. */
5158 if (files_same(root_init_path
, root_systemd_path
) > 0)
5162 r
= acquire_bus(BUS_MANAGER
, &bus
);
5166 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5168 r
= sd_bus_call_method(
5170 "org.freedesktop.systemd1",
5171 "/org/freedesktop/systemd1",
5172 "org.freedesktop.systemd1.Manager",
5178 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5183 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5184 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5185 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5193 polkit_agent_open_if_enabled();
5195 r
= acquire_bus(BUS_MANAGER
, &bus
);
5199 method
= streq(argv
[0], "set-environment")
5201 : "UnsetEnvironment";
5203 r
= sd_bus_message_new_method_call(
5206 "org.freedesktop.systemd1",
5207 "/org/freedesktop/systemd1",
5208 "org.freedesktop.systemd1.Manager",
5211 return bus_log_create_error(r
);
5213 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5215 return bus_log_create_error(r
);
5217 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5219 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5224 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5225 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5226 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5230 polkit_agent_open_if_enabled();
5232 r
= acquire_bus(BUS_MANAGER
, &bus
);
5236 r
= sd_bus_message_new_method_call(
5239 "org.freedesktop.systemd1",
5240 "/org/freedesktop/systemd1",
5241 "org.freedesktop.systemd1.Manager",
5244 return bus_log_create_error(r
);
5247 r
= sd_bus_message_append_strv(m
, environ
);
5251 r
= sd_bus_message_open_container(m
, 'a', "s");
5253 return bus_log_create_error(r
);
5255 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5257 if (!env_name_is_valid(*a
)) {
5258 log_error("Not a valid environment variable name: %s", *a
);
5262 STRV_FOREACH(b
, environ
) {
5265 eq
= startswith(*b
, *a
);
5266 if (eq
&& *eq
== '=') {
5268 r
= sd_bus_message_append(m
, "s", *b
);
5270 return bus_log_create_error(r
);
5277 r
= sd_bus_message_close_container(m
);
5280 return bus_log_create_error(r
);
5282 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5284 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5289 static int enable_sysv_units(const char *verb
, char **args
) {
5292 #if defined(HAVE_SYSV_COMPAT)
5293 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5296 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5298 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5301 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5304 if (!STR_IN_SET(verb
,
5310 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5317 const char *argv
[] = {
5318 ROOTLIBEXECDIR
"/systemd-sysv-install",
5325 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5326 bool found_native
= false, found_sysv
;
5335 if (!endswith(name
, ".service"))
5338 if (path_is_absolute(name
))
5341 j
= unit_file_exists(arg_scope
, &paths
, name
);
5342 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5343 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5344 found_native
= j
!= 0;
5346 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5347 * prefer the native unit */
5348 if (found_native
&& streq(verb
, "is-enabled"))
5351 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5355 p
[strlen(p
) - strlen(".service")] = 0;
5356 found_sysv
= access(p
, F_OK
) >= 0;
5361 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5363 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5365 if (!isempty(arg_root
))
5366 argv
[c
++] = q
= strappend("--root=", arg_root
);
5369 argv
[c
++] = basename(p
);
5372 l
= strv_join((char**)argv
, " ");
5376 log_info("Executing: %s", l
);
5380 return log_error_errno(errno
, "Failed to fork: %m");
5381 else if (pid
== 0) {
5384 (void) reset_all_signal_handlers();
5385 (void) reset_signal_mask();
5387 execv(argv
[0], (char**) argv
);
5388 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
5389 _exit(EXIT_FAILURE
);
5392 j
= wait_for_terminate(pid
, &status
);
5394 log_error_errno(j
, "Failed to wait for child: %m");
5398 if (status
.si_code
== CLD_EXITED
) {
5399 if (streq(verb
, "is-enabled")) {
5400 if (status
.si_status
== 0) {
5409 } else if (status
.si_status
!= 0)
5410 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
5412 log_error("Unexpected waitid() result.");
5419 /* Remove this entry, so that we don't try enabling it as native unit */
5422 assert(args
[f
] == name
);
5423 strv_remove(args
, name
);
5430 static int mangle_names(char **original_names
, char ***mangled_names
) {
5431 char **i
, **l
, **name
;
5434 l
= i
= new(char*, strv_length(original_names
) + 1);
5438 STRV_FOREACH(name
, original_names
) {
5440 /* When enabling units qualified path names are OK,
5441 * too, hence allow them explicitly. */
5443 if (is_path(*name
)) {
5450 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5453 return log_error_errno(r
, "Failed to mangle unit name: %m");
5466 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5467 _cleanup_strv_free_
char **names
= NULL
;
5468 const char *verb
= argv
[0];
5469 UnitFileChange
*changes
= NULL
;
5470 unsigned n_changes
= 0;
5471 int carries_install_info
= -1;
5472 bool ignore_carries_install_info
= arg_quiet
;
5478 r
= mangle_names(strv_skip(argv
, 1), &names
);
5482 r
= enable_sysv_units(verb
, names
);
5486 /* If the operation was fully executed by the SysV compat, let's finish early */
5487 if (strv_isempty(names
)) {
5488 if (arg_no_reload
|| install_client_side())
5490 return daemon_reload(argc
, argv
, userdata
);
5493 if (install_client_side()) {
5494 if (streq(verb
, "enable")) {
5495 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5496 carries_install_info
= r
;
5497 } else if (streq(verb
, "disable"))
5498 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5499 else if (streq(verb
, "reenable")) {
5500 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5501 carries_install_info
= r
;
5502 } else if (streq(verb
, "link"))
5503 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5504 else if (streq(verb
, "preset")) {
5505 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5506 } else if (streq(verb
, "mask"))
5507 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5508 else if (streq(verb
, "unmask"))
5509 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5510 else if (streq(verb
, "revert"))
5511 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
5513 assert_not_reached("Unknown verb");
5515 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
5520 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5521 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5522 bool expect_carries_install_info
= false;
5523 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
5527 polkit_agent_open_if_enabled();
5529 r
= acquire_bus(BUS_MANAGER
, &bus
);
5533 if (streq(verb
, "enable")) {
5534 method
= "EnableUnitFiles";
5535 expect_carries_install_info
= true;
5536 } else if (streq(verb
, "disable")) {
5537 method
= "DisableUnitFiles";
5539 } else if (streq(verb
, "reenable")) {
5540 method
= "ReenableUnitFiles";
5541 expect_carries_install_info
= true;
5542 } else if (streq(verb
, "link"))
5543 method
= "LinkUnitFiles";
5544 else if (streq(verb
, "preset")) {
5546 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5547 method
= "PresetUnitFilesWithMode";
5548 send_preset_mode
= true;
5550 method
= "PresetUnitFiles";
5552 expect_carries_install_info
= true;
5553 ignore_carries_install_info
= true;
5554 } else if (streq(verb
, "mask"))
5555 method
= "MaskUnitFiles";
5556 else if (streq(verb
, "unmask")) {
5557 method
= "UnmaskUnitFiles";
5559 } else if (streq(verb
, "revert")) {
5560 method
= "RevertUnitFiles";
5561 send_runtime
= send_force
= false;
5563 assert_not_reached("Unknown verb");
5565 r
= sd_bus_message_new_method_call(
5568 "org.freedesktop.systemd1",
5569 "/org/freedesktop/systemd1",
5570 "org.freedesktop.systemd1.Manager",
5573 return bus_log_create_error(r
);
5575 r
= sd_bus_message_append_strv(m
, names
);
5577 return bus_log_create_error(r
);
5579 if (send_preset_mode
) {
5580 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5582 return bus_log_create_error(r
);
5586 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5588 return bus_log_create_error(r
);
5592 r
= sd_bus_message_append(m
, "b", arg_force
);
5594 return bus_log_create_error(r
);
5597 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5599 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
5601 if (expect_carries_install_info
) {
5602 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5604 return bus_log_parse_error(r
);
5607 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5611 /* Try to reload if enabled */
5613 r
= daemon_reload(argc
, argv
, userdata
);
5618 if (carries_install_info
== 0 && !ignore_carries_install_info
)
5619 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
5620 "settings in the [Install] section, and DefaultInstance for template units).\n"
5621 "This means they are not meant to be enabled using systemctl.\n"
5622 "Possible reasons for having this kind of units are:\n"
5623 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5624 " .wants/ or .requires/ directory.\n"
5625 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5626 " a requirement dependency on it.\n"
5627 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5628 " D-Bus, udev, scripted systemctl call, ...).\n"
5629 "4) In case of template units, the unit is meant to be enabled with some\n"
5630 " instance name specified.");
5632 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5633 char *new_args
[n_changes
+ 2];
5637 r
= acquire_bus(BUS_MANAGER
, &bus
);
5641 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5642 for (i
= 0; i
< n_changes
; i
++)
5643 new_args
[i
+ 1] = basename(changes
[i
].path
);
5644 new_args
[i
+ 1] = NULL
;
5646 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5650 unit_file_changes_free(changes
, n_changes
);
5655 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5656 _cleanup_strv_free_
char **names
= NULL
;
5657 _cleanup_free_
char *target
= NULL
;
5658 const char *verb
= argv
[0];
5659 UnitFileChange
*changes
= NULL
;
5660 unsigned n_changes
= 0;
5667 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5669 return log_error_errno(r
, "Failed to mangle unit name: %m");
5671 r
= mangle_names(strv_skip(argv
, 2), &names
);
5675 if (streq(verb
, "add-wants"))
5677 else if (streq(verb
, "add-requires"))
5678 dep
= UNIT_REQUIRES
;
5680 assert_not_reached("Unknown verb");
5682 if (install_client_side()) {
5683 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5684 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
5689 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5690 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5693 polkit_agent_open_if_enabled();
5695 r
= acquire_bus(BUS_MANAGER
, &bus
);
5699 r
= sd_bus_message_new_method_call(
5702 "org.freedesktop.systemd1",
5703 "/org/freedesktop/systemd1",
5704 "org.freedesktop.systemd1.Manager",
5705 "AddDependencyUnitFiles");
5707 return bus_log_create_error(r
);
5709 r
= sd_bus_message_append_strv(m
, names
);
5711 return bus_log_create_error(r
);
5713 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5715 return bus_log_create_error(r
);
5717 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5719 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
5721 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5725 if (arg_no_reload
) {
5730 r
= daemon_reload(argc
, argv
, userdata
);
5734 unit_file_changes_free(changes
, n_changes
);
5739 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5740 UnitFileChange
*changes
= NULL
;
5741 unsigned n_changes
= 0;
5744 if (install_client_side()) {
5745 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5746 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
5751 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5752 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5755 polkit_agent_open_if_enabled();
5757 r
= acquire_bus(BUS_MANAGER
, &bus
);
5761 r
= sd_bus_call_method(
5763 "org.freedesktop.systemd1",
5764 "/org/freedesktop/systemd1",
5765 "org.freedesktop.systemd1.Manager",
5766 "PresetAllUnitFiles",
5770 unit_file_preset_mode_to_string(arg_preset_mode
),
5774 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
5776 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5780 if (arg_no_reload
) {
5785 r
= daemon_reload(argc
, argv
, userdata
);
5789 unit_file_changes_free(changes
, n_changes
);
5794 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5796 _cleanup_strv_free_
char **names
= NULL
;
5801 r
= mangle_names(strv_skip(argv
, 1), &names
);
5805 r
= enable_sysv_units(argv
[0], names
);
5811 if (install_client_side()) {
5813 STRV_FOREACH(name
, names
) {
5814 UnitFileState state
;
5816 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5818 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5822 UNIT_FILE_ENABLED_RUNTIME
,
5825 UNIT_FILE_GENERATED
))
5829 puts(unit_file_state_to_string(state
));
5834 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5837 r
= acquire_bus(BUS_MANAGER
, &bus
);
5841 STRV_FOREACH(name
, names
) {
5842 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5845 r
= sd_bus_call_method(
5847 "org.freedesktop.systemd1",
5848 "/org/freedesktop/systemd1",
5849 "org.freedesktop.systemd1.Manager",
5855 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5857 r
= sd_bus_message_read(reply
, "s", &s
);
5859 return bus_log_parse_error(r
);
5861 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
5869 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
5872 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5873 _cleanup_free_
char *state
= NULL
;
5877 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5880 return EXIT_FAILURE
;
5883 r
= acquire_bus(BUS_MANAGER
, &bus
);
5887 r
= sd_bus_get_property_string(
5889 "org.freedesktop.systemd1",
5890 "/org/freedesktop/systemd1",
5891 "org.freedesktop.systemd1.Manager",
5904 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5907 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5908 _cleanup_free_
char *t
= NULL
;
5912 assert(original_path
);
5915 r
= tempfn_random(new_path
, NULL
, &t
);
5917 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5919 r
= mkdir_parents(new_path
, 0755);
5921 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5923 r
= copy_file(original_path
, t
, 0, 0644, 0);
5928 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5931 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5939 static int get_file_to_edit(
5940 const LookupPaths
*paths
,
5944 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
5949 path
= strjoin(paths
->persistent_config
, "/", name
, NULL
);
5954 run
= strjoin(paths
->runtime_config
, name
, NULL
);
5960 if (access(path
, F_OK
) >= 0) {
5961 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5975 static int unit_file_create_dropin(
5976 const LookupPaths
*paths
,
5977 const char *unit_name
,
5978 char **ret_new_path
,
5979 char **ret_tmp_path
) {
5981 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5985 assert(ret_new_path
);
5986 assert(ret_tmp_path
);
5988 ending
= strjoina(unit_name
, ".d/override.conf");
5989 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
5993 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5999 *ret_new_path
= tmp_new_path
;
6000 *ret_tmp_path
= tmp_tmp_path
;
6005 static int unit_file_create_copy(
6006 const LookupPaths
*paths
,
6007 const char *unit_name
,
6008 const char *fragment_path
,
6009 char **ret_new_path
,
6010 char **ret_tmp_path
) {
6012 char *tmp_new_path
, *tmp_tmp_path
;
6015 assert(fragment_path
);
6017 assert(ret_new_path
);
6018 assert(ret_tmp_path
);
6020 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6024 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6027 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6032 if (response
!= 'y') {
6033 log_warning("%s ignored", unit_name
);
6039 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6041 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6046 *ret_new_path
= tmp_new_path
;
6047 *ret_tmp_path
= tmp_tmp_path
;
6052 static int run_editor(char **paths
) {
6060 return log_error_errno(errno
, "Failed to fork: %m");
6064 char *editor
, **editor_args
= NULL
;
6065 char **tmp_path
, **original_path
, *p
;
6066 unsigned n_editor_args
= 0, i
= 1;
6069 (void) reset_all_signal_handlers();
6070 (void) reset_signal_mask();
6072 argc
= strv_length(paths
)/2 + 1;
6074 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6075 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6076 * we try to execute well known editors
6078 editor
= getenv("SYSTEMD_EDITOR");
6080 editor
= getenv("EDITOR");
6082 editor
= getenv("VISUAL");
6084 if (!isempty(editor
)) {
6085 editor_args
= strv_split(editor
, WHITESPACE
);
6088 _exit(EXIT_FAILURE
);
6090 n_editor_args
= strv_length(editor_args
);
6091 argc
+= n_editor_args
- 1;
6093 args
= newa(const char*, argc
+ 1);
6095 if (n_editor_args
> 0) {
6096 args
[0] = editor_args
[0];
6097 for (; i
< n_editor_args
; i
++)
6098 args
[i
] = editor_args
[i
];
6101 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6102 args
[i
] = *tmp_path
;
6107 if (n_editor_args
> 0)
6108 execvp(args
[0], (char* const*) args
);
6110 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6112 execvp(p
, (char* const*) args
);
6113 /* We do not fail if the editor doesn't exist
6114 * because we want to try each one of them before
6117 if (errno
!= ENOENT
) {
6118 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6119 _exit(EXIT_FAILURE
);
6123 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6124 _exit(EXIT_FAILURE
);
6127 r
= wait_for_terminate_and_warn("editor", pid
, true);
6129 return log_error_errno(r
, "Failed to wait for child: %m");
6134 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6135 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6142 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6146 STRV_FOREACH(name
, names
) {
6147 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
;
6149 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6155 // FIXME: support units with path==NULL (no FragmentPath)
6156 log_error("No fragment exists for %s.", *name
);
6161 r
= unit_file_create_copy(&lp
, *name
, path
, &new_path
, &tmp_path
);
6163 r
= unit_file_create_dropin(&lp
, *name
, &new_path
, &tmp_path
);
6167 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6170 new_path
= tmp_path
= NULL
;
6176 static int edit(int argc
, char *argv
[], void *userdata
) {
6177 _cleanup_strv_free_
char **names
= NULL
;
6178 _cleanup_strv_free_
char **paths
= NULL
;
6179 char **original
, **tmp
;
6184 log_error("Cannot edit units if not on a tty.");
6188 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6189 log_error("Cannot edit units remotely.");
6193 r
= acquire_bus(BUS_MANAGER
, &bus
);
6197 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6199 return log_error_errno(r
, "Failed to expand names: %m");
6201 r
= find_paths_to_edit(bus
, names
, &paths
);
6205 if (strv_isempty(paths
))
6208 r
= run_editor(paths
);
6212 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6213 /* If the temporary file is empty we ignore it. It's
6214 * useful if the user wants to cancel its modification
6216 if (null_or_empty_path(*tmp
)) {
6217 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6221 r
= rename(*tmp
, *original
);
6223 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6230 if (!arg_no_reload
&& !install_client_side())
6231 r
= daemon_reload(argc
, argv
, userdata
);
6234 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6235 (void) unlink(*tmp
);
6237 /* Removing empty dropin dirs */
6239 _cleanup_free_
char *dir
;
6241 dir
= dirname_malloc(*original
);
6245 /* no need to check if the dir is empty, rmdir
6246 * does nothing if it is not the case.
6255 static void systemctl_help(void) {
6257 pager_open(arg_no_pager
, false);
6259 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6260 "Query or send control commands to the systemd manager.\n\n"
6261 " -h --help Show this help\n"
6262 " --version Show package version\n"
6263 " --system Connect to system manager\n"
6264 " --user Connect to user service manager\n"
6265 " -H --host=[USER@]HOST\n"
6266 " Operate on remote host\n"
6267 " -M --machine=CONTAINER\n"
6268 " Operate on local container\n"
6269 " -t --type=TYPE List units of a particular type\n"
6270 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6271 " -p --property=NAME Show only properties by this name\n"
6272 " -a --all Show all loaded units/properties, including dead/empty\n"
6273 " ones. To list all units installed on the system, use\n"
6274 " the 'list-unit-files' command instead.\n"
6275 " -l --full Don't ellipsize unit names on output\n"
6276 " -r --recursive Show unit list of host and local containers\n"
6277 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6278 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6279 " queueing a new job\n"
6280 " --show-types When showing sockets, explicitly show their type\n"
6281 " --value When showing properties, only print the value\n"
6282 " -i --ignore-inhibitors\n"
6283 " When shutting down or sleeping, ignore inhibitors\n"
6284 " --kill-who=WHO Who to send signal to\n"
6285 " -s --signal=SIGNAL Which signal to send\n"
6286 " --now Start or stop unit in addition to enabling or disabling it\n"
6287 " -q --quiet Suppress output\n"
6288 " --no-block Do not wait until operation finished\n"
6289 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6290 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6291 " --no-legend Do not print a legend (column headers and hints)\n"
6292 " --no-pager Do not pipe output into a pager\n"
6293 " --no-ask-password\n"
6294 " Do not ask for system passwords\n"
6295 " --global Enable/disable unit files globally\n"
6296 " --runtime Enable unit files only temporarily until next reboot\n"
6297 " -f --force When enabling unit files, override existing symlinks\n"
6298 " When shutting down, execute action immediately\n"
6299 " --preset-mode= Apply only enable, only disable, or all presets\n"
6300 " --root=PATH Enable unit files in the specified root directory\n"
6301 " -n --lines=INTEGER Number of journal entries to show\n"
6302 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6303 " short-precise, short-monotonic, verbose,\n"
6304 " export, json, json-pretty, json-sse, cat)\n"
6305 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6306 " --plain Print unit dependencies as a list instead of a tree\n\n"
6308 " list-units [PATTERN...] List loaded units\n"
6309 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6310 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6311 " start NAME... Start (activate) one or more units\n"
6312 " stop NAME... Stop (deactivate) one or more units\n"
6313 " reload NAME... Reload one or more units\n"
6314 " restart NAME... Start or restart one or more units\n"
6315 " try-restart NAME... Restart one or more units if active\n"
6316 " reload-or-restart NAME... Reload one or more units if possible,\n"
6317 " otherwise start or restart\n"
6318 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6319 " if supported, otherwise restart\n"
6320 " isolate NAME Start one unit and stop all others\n"
6321 " kill NAME... Send signal to processes of a unit\n"
6322 " is-active PATTERN... Check whether units are active\n"
6323 " is-failed PATTERN... Check whether units are failed\n"
6324 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6325 " show [PATTERN...|JOB...] Show properties of one or more\n"
6326 " units/jobs or the manager\n"
6327 " cat PATTERN... Show files and drop-ins of one or more units\n"
6328 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6329 " help PATTERN...|PID... Show manual for one or more units\n"
6330 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6332 " list-dependencies [NAME] Recursively show units which are required\n"
6333 " or wanted by this unit or by which this\n"
6334 " unit is required or wanted\n\n"
6335 "Unit File Commands:\n"
6336 " list-unit-files [PATTERN...] List installed unit files\n"
6337 " enable NAME... Enable one or more unit files\n"
6338 " disable NAME... Disable one or more unit files\n"
6339 " reenable NAME... Reenable one or more unit files\n"
6340 " preset NAME... Enable/disable one or more unit files\n"
6341 " based on preset configuration\n"
6342 " preset-all Enable/disable all unit files based on\n"
6343 " preset configuration\n"
6344 " is-enabled NAME... Check whether unit files are enabled\n"
6345 " mask NAME... Mask one or more units\n"
6346 " unmask NAME... Unmask one or more units\n"
6347 " link PATH... Link one or more units files into\n"
6348 " the search path\n"
6349 " revert NAME... Revert one or more unit files to vendor\n"
6351 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6352 " on specified one or more units\n"
6353 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6354 " on specified one or more units\n"
6355 " edit NAME... Edit one or more unit files\n"
6356 " get-default Get the name of the default target\n"
6357 " set-default NAME Set the default target\n\n"
6358 "Machine Commands:\n"
6359 " list-machines [PATTERN...] List local containers and host\n\n"
6361 " list-jobs [PATTERN...] List jobs\n"
6362 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6363 "Environment Commands:\n"
6364 " show-environment Dump environment\n"
6365 " set-environment NAME=VALUE... Set one or more environment variables\n"
6366 " unset-environment NAME... Unset one or more environment variables\n"
6367 " import-environment [NAME...] Import all or some environment variables\n\n"
6368 "Manager Lifecycle Commands:\n"
6369 " daemon-reload Reload systemd manager configuration\n"
6370 " daemon-reexec Reexecute systemd manager\n\n"
6371 "System Commands:\n"
6372 " is-system-running Check whether system is fully running\n"
6373 " default Enter system default mode\n"
6374 " rescue Enter system rescue mode\n"
6375 " emergency Enter system emergency mode\n"
6376 " halt Shut down and halt the system\n"
6377 " poweroff Shut down and power-off the system\n"
6378 " reboot [ARG] Shut down and reboot the system\n"
6379 " kexec Shut down and reboot the system with kexec\n"
6380 " exit [EXIT_CODE] Request user instance or container exit\n"
6381 " switch-root ROOT [INIT] Change to a different root file system\n"
6382 " suspend Suspend the system\n"
6383 " hibernate Hibernate the system\n"
6384 " hybrid-sleep Hibernate and suspend the system\n",
6385 program_invocation_short_name
);
6388 static void halt_help(void) {
6389 printf("%s [OPTIONS...]%s\n\n"
6390 "%s the system.\n\n"
6391 " --help Show this help\n"
6392 " --halt Halt the machine\n"
6393 " -p --poweroff Switch off the machine\n"
6394 " --reboot Reboot the machine\n"
6395 " -f --force Force immediate halt/power-off/reboot\n"
6396 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6397 " -d --no-wtmp Don't write wtmp record\n"
6398 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6399 program_invocation_short_name
,
6400 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6401 arg_action
== ACTION_REBOOT
? "Reboot" :
6402 arg_action
== ACTION_POWEROFF
? "Power off" :
6406 static void shutdown_help(void) {
6407 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6408 "Shut down the system.\n\n"
6409 " --help Show this help\n"
6410 " -H --halt Halt the machine\n"
6411 " -P --poweroff Power-off the machine\n"
6412 " -r --reboot Reboot the machine\n"
6413 " -h Equivalent to --poweroff, overridden by --halt\n"
6414 " -k Don't halt/power-off/reboot, just send warnings\n"
6415 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6416 " -c Cancel a pending shutdown\n",
6417 program_invocation_short_name
);
6420 static void telinit_help(void) {
6421 printf("%s [OPTIONS...] {COMMAND}\n\n"
6422 "Send control commands to the init daemon.\n\n"
6423 " --help Show this help\n"
6424 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6426 " 0 Power-off the machine\n"
6427 " 6 Reboot the machine\n"
6428 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6429 " 1, s, S Enter rescue mode\n"
6430 " q, Q Reload init daemon configuration\n"
6431 " u, U Reexecute init daemon\n",
6432 program_invocation_short_name
);
6435 static void runlevel_help(void) {
6436 printf("%s [OPTIONS...]\n\n"
6437 "Prints the previous and current runlevel of the init system.\n\n"
6438 " --help Show this help\n",
6439 program_invocation_short_name
);
6442 static void help_types(void) {
6446 puts("Available unit types:");
6447 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6448 puts(unit_type_to_string(i
));
6451 static void help_states(void) {
6455 puts("Available unit load states:");
6456 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6457 puts(unit_load_state_to_string(i
));
6460 puts("\nAvailable unit active states:");
6461 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6462 puts(unit_active_state_to_string(i
));
6465 puts("\nAvailable automount unit substates:");
6466 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6467 puts(automount_state_to_string(i
));
6470 puts("\nAvailable busname unit substates:");
6471 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6472 puts(busname_state_to_string(i
));
6475 puts("\nAvailable device unit substates:");
6476 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6477 puts(device_state_to_string(i
));
6480 puts("\nAvailable mount unit substates:");
6481 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6482 puts(mount_state_to_string(i
));
6485 puts("\nAvailable path unit substates:");
6486 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6487 puts(path_state_to_string(i
));
6490 puts("\nAvailable scope unit substates:");
6491 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6492 puts(scope_state_to_string(i
));
6495 puts("\nAvailable service unit substates:");
6496 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6497 puts(service_state_to_string(i
));
6500 puts("\nAvailable slice unit substates:");
6501 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6502 puts(slice_state_to_string(i
));
6505 puts("\nAvailable socket unit substates:");
6506 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6507 puts(socket_state_to_string(i
));
6510 puts("\nAvailable swap unit substates:");
6511 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6512 puts(swap_state_to_string(i
));
6515 puts("\nAvailable target unit substates:");
6516 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6517 puts(target_state_to_string(i
));
6520 puts("\nAvailable timer unit substates:");
6521 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6522 puts(timer_state_to_string(i
));
6525 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6534 ARG_IGNORE_DEPENDENCIES
,
6547 ARG_NO_ASK_PASSWORD
,
6560 static const struct option options
[] = {
6561 { "help", no_argument
, NULL
, 'h' },
6562 { "version", no_argument
, NULL
, ARG_VERSION
},
6563 { "type", required_argument
, NULL
, 't' },
6564 { "property", required_argument
, NULL
, 'p' },
6565 { "all", no_argument
, NULL
, 'a' },
6566 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6567 { "after", no_argument
, NULL
, ARG_AFTER
},
6568 { "before", no_argument
, NULL
, ARG_BEFORE
},
6569 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6570 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6571 { "full", no_argument
, NULL
, 'l' },
6572 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6573 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6574 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6575 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6576 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6577 { "value", no_argument
, NULL
, ARG_VALUE
},
6578 { "user", no_argument
, NULL
, ARG_USER
},
6579 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6580 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6581 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6582 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6583 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6584 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6585 { "quiet", no_argument
, NULL
, 'q' },
6586 { "root", required_argument
, NULL
, ARG_ROOT
},
6587 { "force", no_argument
, NULL
, ARG_FORCE
},
6588 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6589 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6590 { "signal", required_argument
, NULL
, 's' },
6591 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6592 { "host", required_argument
, NULL
, 'H' },
6593 { "machine", required_argument
, NULL
, 'M' },
6594 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6595 { "lines", required_argument
, NULL
, 'n' },
6596 { "output", required_argument
, NULL
, 'o' },
6597 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6598 { "state", required_argument
, NULL
, ARG_STATE
},
6599 { "recursive", no_argument
, NULL
, 'r' },
6600 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6601 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6602 { "now", no_argument
, NULL
, ARG_NOW
},
6603 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6613 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6614 arg_ask_password
= true;
6616 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6628 if (isempty(optarg
)) {
6629 log_error("--type requires arguments.");
6635 _cleanup_free_
char *type
= NULL
;
6637 r
= extract_first_word(&p
, &type
, ",", 0);
6639 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6644 if (streq(type
, "help")) {
6649 if (unit_type_from_string(type
) >= 0) {
6650 if (strv_push(&arg_types
, type
) < 0)
6656 /* It's much nicer to use --state= for
6657 * load states, but let's support this
6658 * in --types= too for compatibility
6659 * with old versions */
6660 if (unit_load_state_from_string(type
) >= 0) {
6661 if (strv_push(&arg_states
, type
) < 0)
6667 log_error("Unknown unit type or load state '%s'.", type
);
6668 log_info("Use -t help to see a list of allowed values.");
6676 /* Make sure that if the empty property list
6677 was specified, we won't show any properties. */
6678 if (isempty(optarg
) && !arg_properties
) {
6679 arg_properties
= new0(char*, 1);
6680 if (!arg_properties
)
6685 _cleanup_free_
char *prop
= NULL
;
6687 r
= extract_first_word(&p
, &prop
, ",", 0);
6689 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6694 if (strv_push(&arg_properties
, prop
) < 0)
6701 /* If the user asked for a particular
6702 * property, show it to him, even if it is
6714 arg_dependency
= DEPENDENCY_REVERSE
;
6718 arg_dependency
= DEPENDENCY_AFTER
;
6722 arg_dependency
= DEPENDENCY_BEFORE
;
6725 case ARG_SHOW_TYPES
:
6726 arg_show_types
= true;
6734 arg_job_mode
= optarg
;
6738 arg_job_mode
= "fail";
6741 case ARG_IRREVERSIBLE
:
6742 arg_job_mode
= "replace-irreversibly";
6745 case ARG_IGNORE_DEPENDENCIES
:
6746 arg_job_mode
= "ignore-dependencies";
6750 arg_scope
= UNIT_FILE_USER
;
6754 arg_scope
= UNIT_FILE_SYSTEM
;
6758 arg_scope
= UNIT_FILE_GLOBAL
;
6762 arg_no_block
= true;
6766 arg_no_legend
= true;
6770 arg_no_pager
= true;
6778 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
6788 if (strv_extend(&arg_states
, "failed") < 0)
6806 arg_no_reload
= true;
6810 arg_kill_who
= optarg
;
6814 arg_signal
= signal_from_string_try_harder(optarg
);
6815 if (arg_signal
< 0) {
6816 log_error("Failed to parse signal string %s.", optarg
);
6821 case ARG_NO_ASK_PASSWORD
:
6822 arg_ask_password
= false;
6826 arg_transport
= BUS_TRANSPORT_REMOTE
;
6831 arg_transport
= BUS_TRANSPORT_MACHINE
;
6840 if (safe_atou(optarg
, &arg_lines
) < 0) {
6841 log_error("Failed to parse lines '%s'", optarg
);
6847 arg_output
= output_mode_from_string(optarg
);
6848 if (arg_output
< 0) {
6849 log_error("Unknown output '%s'.", optarg
);
6855 arg_ignore_inhibitors
= true;
6862 case ARG_FIRMWARE_SETUP
:
6863 arg_firmware_setup
= true;
6867 if (isempty(optarg
)) {
6868 log_error("--signal requires arguments.");
6874 _cleanup_free_
char *s
= NULL
;
6876 r
= extract_first_word(&p
, &s
, ",", 0);
6878 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6883 if (streq(s
, "help")) {
6888 if (strv_push(&arg_states
, s
) < 0)
6897 if (geteuid() != 0) {
6898 log_error("--recursive requires root privileges.");
6902 arg_recursive
= true;
6905 case ARG_PRESET_MODE
:
6907 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6908 if (arg_preset_mode
< 0) {
6909 log_error("Failed to parse preset mode: %s.", optarg
);
6920 if (strv_extend(&arg_wall
, optarg
) < 0)
6928 assert_not_reached("Unhandled option");
6931 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6932 log_error("Cannot access user instance remotely.");
6939 static int halt_parse_argv(int argc
, char *argv
[]) {
6948 static const struct option options
[] = {
6949 { "help", no_argument
, NULL
, ARG_HELP
},
6950 { "halt", no_argument
, NULL
, ARG_HALT
},
6951 { "poweroff", no_argument
, NULL
, 'p' },
6952 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6953 { "force", no_argument
, NULL
, 'f' },
6954 { "wtmp-only", no_argument
, NULL
, 'w' },
6955 { "no-wtmp", no_argument
, NULL
, 'd' },
6956 { "no-sync", no_argument
, NULL
, 'n' },
6957 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6966 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6967 if (runlevel
== '0' || runlevel
== '6')
6970 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6978 arg_action
= ACTION_HALT
;
6982 if (arg_action
!= ACTION_REBOOT
)
6983 arg_action
= ACTION_POWEROFF
;
6987 arg_action
= ACTION_REBOOT
;
7012 /* Compatibility nops */
7019 assert_not_reached("Unhandled option");
7022 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7023 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7026 } else if (optind
< argc
) {
7027 log_error("Too many arguments.");
7034 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7038 if (streq(t
, "now"))
7040 else if (!strchr(t
, ':')) {
7043 if (safe_atou64(t
, &u
) < 0)
7046 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7055 hour
= strtol(t
, &e
, 10);
7056 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7059 minute
= strtol(e
+1, &e
, 10);
7060 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7063 n
= now(CLOCK_REALTIME
);
7064 s
= (time_t) (n
/ USEC_PER_SEC
);
7066 assert_se(localtime_r(&s
, &tm
));
7068 tm
.tm_hour
= (int) hour
;
7069 tm
.tm_min
= (int) minute
;
7072 assert_se(s
= mktime(&tm
));
7074 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7077 *_u
+= USEC_PER_DAY
;
7083 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7090 static const struct option options
[] = {
7091 { "help", no_argument
, NULL
, ARG_HELP
},
7092 { "halt", no_argument
, NULL
, 'H' },
7093 { "poweroff", no_argument
, NULL
, 'P' },
7094 { "reboot", no_argument
, NULL
, 'r' },
7095 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7096 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7106 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7114 arg_action
= ACTION_HALT
;
7118 arg_action
= ACTION_POWEROFF
;
7123 arg_action
= ACTION_KEXEC
;
7125 arg_action
= ACTION_REBOOT
;
7129 arg_action
= ACTION_KEXEC
;
7133 if (arg_action
!= ACTION_HALT
)
7134 arg_action
= ACTION_POWEROFF
;
7149 /* Compatibility nops */
7153 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7160 assert_not_reached("Unhandled option");
7163 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7164 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7166 log_error("Failed to parse time specification: %s", argv
[optind
]);
7170 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7172 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7173 /* No time argument for shutdown cancel */
7174 wall
= argv
+ optind
;
7175 else if (argc
> optind
+ 1)
7176 /* We skip the time argument */
7177 wall
= argv
+ optind
+ 1;
7180 arg_wall
= strv_copy(wall
);
7190 static int telinit_parse_argv(int argc
, char *argv
[]) {
7197 static const struct option options
[] = {
7198 { "help", no_argument
, NULL
, ARG_HELP
},
7199 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7203 static const struct {
7207 { '0', ACTION_POWEROFF
},
7208 { '6', ACTION_REBOOT
},
7209 { '1', ACTION_RESCUE
},
7210 { '2', ACTION_RUNLEVEL2
},
7211 { '3', ACTION_RUNLEVEL3
},
7212 { '4', ACTION_RUNLEVEL4
},
7213 { '5', ACTION_RUNLEVEL5
},
7214 { 's', ACTION_RESCUE
},
7215 { 'S', ACTION_RESCUE
},
7216 { 'q', ACTION_RELOAD
},
7217 { 'Q', ACTION_RELOAD
},
7218 { 'u', ACTION_REEXEC
},
7219 { 'U', ACTION_REEXEC
}
7228 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7243 assert_not_reached("Unhandled option");
7246 if (optind
>= argc
) {
7247 log_error("%s: required argument missing.", program_invocation_short_name
);
7251 if (optind
+ 1 < argc
) {
7252 log_error("Too many arguments.");
7256 if (strlen(argv
[optind
]) != 1) {
7257 log_error("Expected single character argument.");
7261 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7262 if (table
[i
].from
== argv
[optind
][0])
7265 if (i
>= ELEMENTSOF(table
)) {
7266 log_error("Unknown command '%s'.", argv
[optind
]);
7270 arg_action
= table
[i
].to
;
7277 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7283 static const struct option options
[] = {
7284 { "help", no_argument
, NULL
, ARG_HELP
},
7293 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7304 assert_not_reached("Unhandled option");
7307 if (optind
< argc
) {
7308 log_error("Too many arguments.");
7315 static int parse_argv(int argc
, char *argv
[]) {
7319 if (program_invocation_short_name
) {
7321 if (strstr(program_invocation_short_name
, "halt")) {
7322 arg_action
= ACTION_HALT
;
7323 return halt_parse_argv(argc
, argv
);
7324 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7325 arg_action
= ACTION_POWEROFF
;
7326 return halt_parse_argv(argc
, argv
);
7327 } else if (strstr(program_invocation_short_name
, "reboot")) {
7329 arg_action
= ACTION_KEXEC
;
7331 arg_action
= ACTION_REBOOT
;
7332 return halt_parse_argv(argc
, argv
);
7333 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7334 arg_action
= ACTION_POWEROFF
;
7335 return shutdown_parse_argv(argc
, argv
);
7336 } else if (strstr(program_invocation_short_name
, "init")) {
7338 if (sd_booted() > 0) {
7339 arg_action
= _ACTION_INVALID
;
7340 return telinit_parse_argv(argc
, argv
);
7342 /* Hmm, so some other init system is
7343 * running, we need to forward this
7344 * request to it. For now we simply
7345 * guess that it is Upstart. */
7347 execv(TELINIT
, argv
);
7349 log_error("Couldn't find an alternative telinit implementation to spawn.");
7353 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7354 arg_action
= ACTION_RUNLEVEL
;
7355 return runlevel_parse_argv(argc
, argv
);
7359 arg_action
= ACTION_SYSTEMCTL
;
7360 return systemctl_parse_argv(argc
, argv
);
7363 #ifdef HAVE_SYSV_COMPAT
7364 _pure_
static int action_to_runlevel(void) {
7366 static const char table
[_ACTION_MAX
] = {
7367 [ACTION_HALT
] = '0',
7368 [ACTION_POWEROFF
] = '0',
7369 [ACTION_REBOOT
] = '6',
7370 [ACTION_RUNLEVEL2
] = '2',
7371 [ACTION_RUNLEVEL3
] = '3',
7372 [ACTION_RUNLEVEL4
] = '4',
7373 [ACTION_RUNLEVEL5
] = '5',
7374 [ACTION_RESCUE
] = '1'
7377 assert(arg_action
< _ACTION_MAX
);
7379 return table
[arg_action
];
7383 static int talk_initctl(void) {
7384 #ifdef HAVE_SYSV_COMPAT
7385 struct init_request request
= {
7386 .magic
= INIT_MAGIC
,
7388 .cmd
= INIT_CMD_RUNLVL
7391 _cleanup_close_
int fd
= -1;
7395 rl
= action_to_runlevel();
7399 request
.runlevel
= rl
;
7401 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7403 if (errno
== ENOENT
)
7406 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7409 r
= loop_write(fd
, &request
, sizeof(request
), false);
7411 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7419 static int systemctl_main(int argc
, char *argv
[]) {
7421 static const Verb verbs
[] = {
7422 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7423 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7424 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7425 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7426 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7427 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7428 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7429 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7430 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7431 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7432 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7433 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7434 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7435 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7436 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7437 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7438 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7439 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7440 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7441 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7442 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7443 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7444 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7445 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7446 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7447 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7448 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7449 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7450 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7451 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7452 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7453 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7454 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7455 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7456 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7457 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7458 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7459 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7460 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7461 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7462 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7463 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7464 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7465 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7466 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7467 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7468 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7469 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7470 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7471 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7472 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7473 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7474 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7475 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7476 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7477 { "link", 2, VERB_ANY
, 0, enable_unit
},
7478 { "revert", 2, VERB_ANY
, 0, enable_unit
},
7479 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7480 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7481 { "set-default", 2, 2, 0, set_default
},
7482 { "get-default", VERB_ANY
, 1, 0, get_default
},
7483 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7484 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7485 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7486 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7487 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7491 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7494 static int reload_with_fallback(void) {
7496 /* First, try systemd via D-Bus. */
7497 if (daemon_reload(0, NULL
, NULL
) >= 0)
7500 /* Nothing else worked, so let's try signals */
7501 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7503 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7504 return log_error_errno(errno
, "kill() failed: %m");
7509 static int start_with_fallback(void) {
7511 /* First, try systemd via D-Bus. */
7512 if (start_unit(0, NULL
, NULL
) >= 0)
7515 /* Nothing else worked, so let's try
7517 if (talk_initctl() > 0)
7520 log_error("Failed to talk to init daemon.");
7524 static int halt_now(enum action a
) {
7527 /* The kernel will automaticall flush ATA disks and suchlike
7528 * on reboot(), but the file systems need to be synce'd
7529 * explicitly in advance. */
7533 /* Make sure C-A-D is handled by the kernel from this point
7535 (void) reboot(RB_ENABLE_CAD
);
7540 log_info("Halting.");
7541 (void) reboot(RB_HALT_SYSTEM
);
7544 case ACTION_POWEROFF
:
7545 log_info("Powering off.");
7546 (void) reboot(RB_POWER_OFF
);
7550 case ACTION_REBOOT
: {
7551 _cleanup_free_
char *param
= NULL
;
7553 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
7555 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
7557 if (!isempty(param
)) {
7558 log_info("Rebooting with argument '%s'.", param
);
7559 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7560 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
7563 log_info("Rebooting.");
7564 (void) reboot(RB_AUTOBOOT
);
7569 assert_not_reached("Unknown action.");
7573 static int logind_schedule_shutdown(void) {
7576 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7577 char date
[FORMAT_TIMESTAMP_MAX
];
7582 (void) logind_set_wall_message();
7584 r
= acquire_bus(BUS_FULL
, &bus
);
7588 switch (arg_action
) {
7592 case ACTION_POWEROFF
:
7593 action
= "poweroff";
7608 action
= strjoina("dry-", action
);
7610 r
= sd_bus_call_method(
7612 "org.freedesktop.login1",
7613 "/org/freedesktop/login1",
7614 "org.freedesktop.login1.Manager",
7622 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7624 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7627 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7632 static int halt_main(void) {
7635 r
= logind_check_inhibitors(arg_action
);
7640 return logind_schedule_shutdown();
7642 if (geteuid() != 0) {
7643 if (arg_dry
|| arg_force
> 0) {
7644 log_error("Must be root.");
7648 /* Try logind if we are a normal user and no special
7649 * mode applies. Maybe PolicyKit allows us to shutdown
7651 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7652 r
= logind_reboot(arg_action
);
7655 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7656 /* requested operation is not
7657 * supported on the local system or
7658 * already in progress */
7660 /* on all other errors, try low-level operation */
7664 if (!arg_dry
&& !arg_force
)
7665 return start_with_fallback();
7667 assert(geteuid() == 0);
7670 if (sd_booted() > 0)
7671 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7673 r
= utmp_put_shutdown();
7675 log_warning_errno(r
, "Failed to write utmp record: %m");
7682 r
= halt_now(arg_action
);
7683 return log_error_errno(r
, "Failed to reboot: %m");
7686 static int runlevel_main(void) {
7687 int r
, runlevel
, previous
;
7689 r
= utmp_get_runlevel(&runlevel
, &previous
);
7696 previous
<= 0 ? 'N' : previous
,
7697 runlevel
<= 0 ? 'N' : runlevel
);
7702 static int logind_cancel_shutdown(void) {
7704 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7708 r
= acquire_bus(BUS_FULL
, &bus
);
7712 (void) logind_set_wall_message();
7714 r
= sd_bus_call_method(
7716 "org.freedesktop.login1",
7717 "/org/freedesktop/login1",
7718 "org.freedesktop.login1.Manager",
7719 "CancelScheduledShutdown",
7723 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7727 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7732 int main(int argc
, char*argv
[]) {
7735 setlocale(LC_ALL
, "");
7736 log_parse_environment();
7739 /* Explicitly not on_tty() to avoid setting cached value.
7740 * This becomes relevant for piping output which might be
7742 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7744 r
= parse_argv(argc
, argv
);
7748 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7749 log_info("Running in chroot, ignoring request.");
7754 /* systemctl_main() will print an error message for the bus
7755 * connection, but only if it needs to */
7757 switch (arg_action
) {
7759 case ACTION_SYSTEMCTL
:
7760 r
= systemctl_main(argc
, argv
);
7764 case ACTION_POWEROFF
:
7770 case ACTION_RUNLEVEL2
:
7771 case ACTION_RUNLEVEL3
:
7772 case ACTION_RUNLEVEL4
:
7773 case ACTION_RUNLEVEL5
:
7775 case ACTION_EMERGENCY
:
7776 case ACTION_DEFAULT
:
7777 r
= start_with_fallback();
7782 r
= reload_with_fallback();
7785 case ACTION_CANCEL_SHUTDOWN
:
7786 r
= logind_cancel_shutdown();
7789 case ACTION_RUNLEVEL
:
7790 r
= runlevel_main();
7793 case _ACTION_INVALID
:
7795 assert_not_reached("Unknown action");
7800 ask_password_agent_close();
7801 polkit_agent_close();
7803 strv_free(arg_types
);
7804 strv_free(arg_states
);
7805 strv_free(arg_properties
);
7807 strv_free(arg_wall
);
7812 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7814 return r
< 0 ? EXIT_FAILURE
: r
;