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"
43 #include "cgroup-show.h"
44 #include "cgroup-util.h"
49 #include "exit-status.h"
52 #include "formats-util.h"
54 #include "glob-util.h"
55 #include "hostname-util.h"
60 #include "locale-util.h"
62 #include "logs-show.h"
66 #include "parse-util.h"
67 #include "path-lookup.h"
68 #include "path-util.h"
69 #include "process-util.h"
70 #include "rlimit-util.h"
72 #include "signal-util.h"
73 #include "socket-util.h"
74 #include "spawn-ask-password-agent.h"
75 #include "spawn-polkit-agent.h"
77 #include "stat-util.h"
79 #include "terminal-util.h"
80 #include "unit-name.h"
81 #include "user-util.h"
83 #include "utmp-wtmp.h"
87 static char **arg_types
= NULL
;
88 static char **arg_states
= NULL
;
89 static char **arg_properties
= NULL
;
90 static bool arg_all
= false;
91 static enum dependency
{
97 } arg_dependency
= DEPENDENCY_FORWARD
;
98 static const char *arg_job_mode
= "replace";
99 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
100 static bool arg_no_block
= false;
101 static bool arg_no_legend
= false;
102 static bool arg_no_pager
= false;
103 static bool arg_no_wtmp
= false;
104 static bool arg_no_wall
= false;
105 static bool arg_no_reload
= false;
106 static bool arg_show_types
= false;
107 static bool arg_ignore_inhibitors
= false;
108 static bool arg_dry
= false;
109 static bool arg_quiet
= false;
110 static bool arg_full
= false;
111 static bool arg_recursive
= false;
112 static int arg_force
= 0;
113 static bool arg_ask_password
= false;
114 static bool arg_runtime
= false;
115 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
116 static char **arg_wall
= NULL
;
117 static const char *arg_kill_who
= NULL
;
118 static int arg_signal
= SIGTERM
;
119 static char *arg_root
= NULL
;
120 static usec_t arg_when
= 0;
142 ACTION_CANCEL_SHUTDOWN
,
144 } arg_action
= ACTION_SYSTEMCTL
;
145 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
146 static const char *arg_host
= NULL
;
147 static unsigned arg_lines
= 10;
148 static OutputMode arg_output
= OUTPUT_SHORT
;
149 static bool arg_plain
= false;
150 static bool arg_firmware_setup
= false;
151 static bool arg_now
= false;
153 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
154 static int halt_now(enum action a
);
155 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
157 static bool original_stdout_is_tty
;
159 typedef enum BusFocus
{
160 BUS_FULL
, /* The full bus indicated via --system or --user */
161 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
165 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
167 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
170 assert(focus
< _BUS_FOCUS_MAX
);
173 /* We only go directly to the manager, if we are using a local transport */
174 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
177 if (!busses
[focus
]) {
180 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
182 if (focus
== BUS_MANAGER
)
183 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
185 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
187 return log_error_errno(r
, "Failed to connect to bus: %m");
189 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
192 *ret
= busses
[focus
];
196 static void release_busses(void) {
199 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
200 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
203 static void ask_password_agent_open_if_enabled(void) {
205 /* Open the password agent as a child process if necessary */
207 if (!arg_ask_password
)
210 if (arg_scope
!= UNIT_FILE_SYSTEM
)
213 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
216 ask_password_agent_open();
219 static void polkit_agent_open_if_enabled(void) {
221 /* Open the polkit agent as a child process if necessary */
223 if (!arg_ask_password
)
226 if (arg_scope
!= UNIT_FILE_SYSTEM
)
229 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
235 static OutputFlags
get_output_flags(void) {
237 arg_all
* OUTPUT_SHOW_ALL
|
238 arg_full
* OUTPUT_FULL_WIDTH
|
239 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
240 colors_enabled() * OUTPUT_COLOR
|
241 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
244 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
247 if (!sd_bus_error_is_set(error
))
250 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
251 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
252 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
253 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
254 return EXIT_NOPERMISSION
;
256 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
257 return EXIT_NOTINSTALLED
;
259 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
260 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
261 return EXIT_NOTIMPLEMENTED
;
263 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
264 return EXIT_NOTCONFIGURED
;
272 static bool install_client_side(void) {
274 /* Decides when to execute enable/disable/... operations
275 * client-side rather than server-side. */
277 if (running_in_chroot() > 0)
280 if (sd_booted() <= 0)
283 if (!isempty(arg_root
))
286 if (arg_scope
== UNIT_FILE_GLOBAL
)
289 /* Unsupported environment variable, mostly for debugging purposes */
290 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
296 static int compare_unit_info(const void *a
, const void *b
) {
297 const UnitInfo
*u
= a
, *v
= b
;
301 /* First, order by machine */
302 if (!u
->machine
&& v
->machine
)
304 if (u
->machine
&& !v
->machine
)
306 if (u
->machine
&& v
->machine
) {
307 r
= strcasecmp(u
->machine
, v
->machine
);
312 /* Second, order by unit type */
313 d1
= strrchr(u
->id
, '.');
314 d2
= strrchr(v
->id
, '.');
316 r
= strcasecmp(d1
, d2
);
321 /* Third, order by name */
322 return strcasecmp(u
->id
, v
->id
);
325 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
326 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
332 dot
= strrchr(u
->id
, '.');
336 if (!strv_find(arg_types
, dot
+1))
346 if (streq(u
->active_state
, "inactive") || u
->following
[0])
352 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
353 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
355 unsigned n_shown
= 0;
358 max_id_len
= strlen("UNIT");
359 load_len
= strlen("LOAD");
360 active_len
= strlen("ACTIVE");
361 sub_len
= strlen("SUB");
362 job_len
= strlen("JOB");
365 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
366 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
367 load_len
= MAX(load_len
, strlen(u
->load_state
));
368 active_len
= MAX(active_len
, strlen(u
->active_state
));
369 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
371 if (u
->job_id
!= 0) {
372 job_len
= MAX(job_len
, strlen(u
->job_type
));
376 if (!arg_no_legend
&&
377 (streq(u
->active_state
, "failed") ||
378 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
382 if (!arg_full
&& original_stdout_is_tty
) {
385 id_len
= MIN(max_id_len
, 25u);
386 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
389 basic_len
+= job_len
+ 1;
391 if (basic_len
< (unsigned) columns()) {
392 unsigned extra_len
, incr
;
393 extra_len
= columns() - basic_len
;
395 /* Either UNIT already got 25, or is fully satisfied.
396 * Grant up to 25 to DESC now. */
397 incr
= MIN(extra_len
, 25u);
401 /* split the remaining space between UNIT and DESC,
402 * but do not give UNIT more than it needs. */
404 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
406 desc_len
+= extra_len
- incr
;
412 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
413 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
414 const char *on_loaded
= "", *off_loaded
= "";
415 const char *on_active
= "", *off_active
= "";
416 const char *on_circle
= "", *off_circle
= "";
420 if (!n_shown
&& !arg_no_legend
) {
425 printf("%-*s %-*s %-*s %-*s ",
428 active_len
, "ACTIVE",
432 printf("%-*s ", job_len
, "JOB");
434 if (!arg_full
&& arg_no_pager
)
435 printf("%.*s\n", desc_len
, "DESCRIPTION");
437 printf("%s\n", "DESCRIPTION");
442 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
443 on_loaded
= ansi_highlight_red();
444 on_circle
= ansi_highlight_yellow();
445 off_loaded
= off_circle
= ansi_normal();
447 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
448 on_circle
= on_active
= ansi_highlight_red();
449 off_circle
= off_active
= ansi_normal();
454 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
463 e
= ellipsize(id
, id_len
, 33);
471 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
473 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
474 on_active
, id_len
, id
, off_active
,
475 on_loaded
, load_len
, u
->load_state
, off_loaded
,
476 on_active
, active_len
, u
->active_state
,
477 sub_len
, u
->sub_state
, off_active
,
478 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
481 printf("%.*s\n", desc_len
, u
->description
);
483 printf("%s\n", u
->description
);
486 if (!arg_no_legend
) {
487 const char *on
, *off
;
491 "LOAD = Reflects whether the unit definition was properly loaded.\n"
492 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
493 "SUB = The low-level unit activation state, values depend on unit type.");
494 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
495 on
= ansi_highlight();
498 on
= ansi_highlight_red();
503 printf("%s%u loaded units listed.%s\n"
504 "To show all installed unit files use 'systemctl list-unit-files'.\n",
507 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
508 "To show all installed unit files use 'systemctl list-unit-files'.\n",
515 static int get_unit_list(
519 UnitInfo
**unit_infos
,
521 sd_bus_message
**_reply
) {
523 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
524 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
525 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
534 r
= sd_bus_message_new_method_call(
537 "org.freedesktop.systemd1",
538 "/org/freedesktop/systemd1",
539 "org.freedesktop.systemd1.Manager",
540 "ListUnitsFiltered");
543 return bus_log_create_error(r
);
545 r
= sd_bus_message_append_strv(m
, arg_states
);
547 return bus_log_create_error(r
);
549 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
551 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
553 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
555 return bus_log_parse_error(r
);
557 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
560 if (!output_show_unit(&u
, patterns
))
563 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
566 (*unit_infos
)[c
++] = u
;
569 return bus_log_parse_error(r
);
571 r
= sd_bus_message_exit_container(reply
);
573 return bus_log_parse_error(r
);
581 static void message_set_freep(Set
**set
) {
584 while ((m
= set_steal_first(*set
)))
585 sd_bus_message_unref(m
);
590 static int get_unit_list_recursive(
593 UnitInfo
**_unit_infos
,
597 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
598 _cleanup_(message_set_freep
) Set
*replies
;
599 sd_bus_message
*reply
;
607 replies
= set_new(NULL
);
611 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
615 r
= set_put(replies
, reply
);
617 sd_bus_message_unref(reply
);
622 _cleanup_strv_free_
char **machines
= NULL
;
625 r
= sd_get_machine_names(&machines
);
627 return log_error_errno(r
, "Failed to get machine names: %m");
629 STRV_FOREACH(i
, machines
) {
630 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
633 r
= sd_bus_open_system_machine(&container
, *i
);
635 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
639 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
645 r
= set_put(replies
, reply
);
647 sd_bus_message_unref(reply
);
652 *_machines
= machines
;
657 *_unit_infos
= unit_infos
;
666 static int list_units(int argc
, char *argv
[], void *userdata
) {
667 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
668 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
669 _cleanup_strv_free_
char **machines
= NULL
;
673 pager_open(arg_no_pager
, false);
675 r
= acquire_bus(BUS_MANAGER
, &bus
);
679 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
683 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
684 return output_units_list(unit_infos
, r
);
687 static int get_triggered_units(
692 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
699 r
= sd_bus_get_property_strv(
701 "org.freedesktop.systemd1",
703 "org.freedesktop.systemd1.Unit",
708 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
713 static int get_listening(
715 const char* unit_path
,
718 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
719 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
720 const char *type
, *path
;
723 r
= sd_bus_get_property(
725 "org.freedesktop.systemd1",
727 "org.freedesktop.systemd1.Socket",
733 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
735 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
737 return bus_log_parse_error(r
);
739 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
741 r
= strv_extend(listening
, type
);
745 r
= strv_extend(listening
, path
);
752 return bus_log_parse_error(r
);
754 r
= sd_bus_message_exit_container(reply
);
756 return bus_log_parse_error(r
);
768 /* Note: triggered is a list here, although it almost certainly
769 * will always be one unit. Nevertheless, dbus API allows for multiple
770 * values, so let's follow that. */
773 /* The strv above is shared. free is set only in the first one. */
777 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
783 if (!a
->machine
&& b
->machine
)
785 if (a
->machine
&& !b
->machine
)
787 if (a
->machine
&& b
->machine
) {
788 o
= strcasecmp(a
->machine
, b
->machine
);
793 o
= strcmp(a
->path
, b
->path
);
795 o
= strcmp(a
->type
, b
->type
);
800 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
801 struct socket_info
*s
;
802 unsigned pathlen
= strlen("LISTEN"),
803 typelen
= strlen("TYPE") * arg_show_types
,
804 socklen
= strlen("UNIT"),
805 servlen
= strlen("ACTIVATES");
806 const char *on
, *off
;
808 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
812 socklen
= MAX(socklen
, strlen(s
->id
));
814 typelen
= MAX(typelen
, strlen(s
->type
));
815 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
817 STRV_FOREACH(a
, s
->triggered
)
818 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
819 servlen
= MAX(servlen
, tmp
);
824 printf("%-*s %-*.*s%-*s %s\n",
826 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
830 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
831 _cleanup_free_
char *j
= NULL
;
836 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
844 printf("%-*s %-*s %-*s",
845 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
848 pathlen
, path
, socklen
, s
->id
);
849 STRV_FOREACH(a
, s
->triggered
)
851 a
== s
->triggered
? "" : ",", *a
);
855 on
= ansi_highlight();
860 on
= ansi_highlight_red();
864 if (!arg_no_legend
) {
865 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
867 printf("Pass --all to see loaded but inactive sockets, too.\n");
873 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
874 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
875 _cleanup_strv_free_
char **machines
= NULL
;
876 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
877 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
879 struct socket_info
*s
;
885 pager_open(arg_no_pager
, false);
887 r
= acquire_bus(BUS_MANAGER
, &bus
);
891 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
895 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
896 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
899 if (!endswith(u
->id
, ".socket"))
902 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
906 c
= get_listening(bus
, u
->unit_path
, &listening
);
912 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
917 for (i
= 0; i
< c
; i
++)
918 socket_infos
[cs
+ i
] = (struct socket_info
) {
919 .machine
= u
->machine
,
921 .type
= listening
[i
*2],
922 .path
= listening
[i
*2 + 1],
923 .triggered
= triggered
,
924 .own_triggered
= i
==0,
927 /* from this point on we will cleanup those socket_infos */
930 listening
= triggered
= NULL
; /* avoid cleanup */
933 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
934 (__compar_fn_t
) socket_info_compare
);
936 output_sockets_list(socket_infos
, cs
);
939 assert(cs
== 0 || socket_infos
);
940 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
943 if (s
->own_triggered
)
944 strv_free(s
->triggered
);
950 static int get_next_elapse(
953 dual_timestamp
*next
) {
955 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
963 r
= sd_bus_get_property_trivial(
965 "org.freedesktop.systemd1",
967 "org.freedesktop.systemd1.Timer",
968 "NextElapseUSecMonotonic",
973 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
975 r
= sd_bus_get_property_trivial(
977 "org.freedesktop.systemd1",
979 "org.freedesktop.systemd1.Timer",
980 "NextElapseUSecRealtime",
985 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
991 static int get_last_trigger(
996 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1003 r
= sd_bus_get_property_trivial(
1005 "org.freedesktop.systemd1",
1007 "org.freedesktop.systemd1.Timer",
1013 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1019 const char* machine
;
1022 usec_t last_trigger
;
1026 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1032 if (!a
->machine
&& b
->machine
)
1034 if (a
->machine
&& !b
->machine
)
1036 if (a
->machine
&& b
->machine
) {
1037 o
= strcasecmp(a
->machine
, b
->machine
);
1042 if (a
->next_elapse
< b
->next_elapse
)
1044 if (a
->next_elapse
> b
->next_elapse
)
1047 return strcmp(a
->id
, b
->id
);
1050 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1051 struct timer_info
*t
;
1053 nextlen
= strlen("NEXT"),
1054 leftlen
= strlen("LEFT"),
1055 lastlen
= strlen("LAST"),
1056 passedlen
= strlen("PASSED"),
1057 unitlen
= strlen("UNIT"),
1058 activatelen
= strlen("ACTIVATES");
1060 const char *on
, *off
;
1062 assert(timer_infos
|| n
== 0);
1064 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1068 if (t
->next_elapse
> 0) {
1069 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1071 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1072 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1074 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1075 leftlen
= MAX(leftlen
, strlen(trel
));
1078 if (t
->last_trigger
> 0) {
1079 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1081 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1082 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1084 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1085 passedlen
= MAX(passedlen
, strlen(trel
));
1088 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1090 STRV_FOREACH(a
, t
->triggered
)
1091 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1093 activatelen
= MAX(activatelen
, ul
);
1098 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1102 passedlen
, "PASSED",
1106 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1107 _cleanup_free_
char *j
= NULL
;
1109 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1110 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1113 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1114 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1116 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1117 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1120 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1127 printf("%-*s %-*s %-*s %-*s %-*s",
1128 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1130 STRV_FOREACH(a
, t
->triggered
)
1132 a
== t
->triggered
? "" : ",", *a
);
1136 on
= ansi_highlight();
1137 off
= ansi_normal();
1141 on
= ansi_highlight_red();
1142 off
= ansi_normal();
1145 if (!arg_no_legend
) {
1146 printf("%s%u timers listed.%s\n", on
, n
, off
);
1148 printf("Pass --all to see loaded but inactive timers, too.\n");
1154 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1160 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1163 if (next
->monotonic
> nw
->monotonic
)
1164 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1166 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1168 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1169 next_elapse
= MIN(converted
, next
->realtime
);
1171 next_elapse
= converted
;
1174 next_elapse
= next
->realtime
;
1179 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1180 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1181 _cleanup_strv_free_
char **machines
= NULL
;
1182 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1183 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1184 struct timer_info
*t
;
1192 pager_open(arg_no_pager
, false);
1194 r
= acquire_bus(BUS_MANAGER
, &bus
);
1198 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1202 dual_timestamp_get(&nw
);
1204 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1205 _cleanup_strv_free_
char **triggered
= NULL
;
1206 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1209 if (!endswith(u
->id
, ".timer"))
1212 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1216 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1220 get_last_trigger(bus
, u
->unit_path
, &last
);
1222 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1227 m
= calc_next_elapse(&nw
, &next
);
1229 timer_infos
[c
++] = (struct timer_info
) {
1230 .machine
= u
->machine
,
1233 .last_trigger
= last
,
1234 .triggered
= triggered
,
1237 triggered
= NULL
; /* avoid cleanup */
1240 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1241 (__compar_fn_t
) timer_info_compare
);
1243 output_timers_list(timer_infos
, c
);
1246 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1247 strv_free(t
->triggered
);
1252 static int compare_unit_file_list(const void *a
, const void *b
) {
1253 const char *d1
, *d2
;
1254 const UnitFileList
*u
= a
, *v
= b
;
1256 d1
= strrchr(u
->path
, '.');
1257 d2
= strrchr(v
->path
, '.');
1262 r
= strcasecmp(d1
, d2
);
1267 return strcasecmp(basename(u
->path
), basename(v
->path
));
1270 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1271 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1274 if (!strv_isempty(arg_types
)) {
1277 dot
= strrchr(u
->path
, '.');
1281 if (!strv_find(arg_types
, dot
+1))
1285 if (!strv_isempty(arg_states
) &&
1286 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1292 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1293 unsigned max_id_len
, id_cols
, state_cols
;
1294 const UnitFileList
*u
;
1296 max_id_len
= strlen("UNIT FILE");
1297 state_cols
= strlen("STATE");
1299 for (u
= units
; u
< units
+ c
; u
++) {
1300 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1301 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1305 unsigned basic_cols
;
1307 id_cols
= MIN(max_id_len
, 25u);
1308 basic_cols
= 1 + id_cols
+ state_cols
;
1309 if (basic_cols
< (unsigned) columns())
1310 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1312 id_cols
= max_id_len
;
1315 printf("%-*s %-*s\n",
1316 id_cols
, "UNIT FILE",
1317 state_cols
, "STATE");
1319 for (u
= units
; u
< units
+ c
; u
++) {
1320 _cleanup_free_
char *e
= NULL
;
1321 const char *on
, *off
;
1324 if (IN_SET(u
->state
,
1326 UNIT_FILE_MASKED_RUNTIME
,
1329 on
= ansi_highlight_red();
1330 off
= ansi_normal();
1331 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1332 on
= ansi_highlight_green();
1333 off
= ansi_normal();
1337 id
= basename(u
->path
);
1339 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1341 printf("%-*s %s%-*s%s\n",
1342 id_cols
, e
? e
: id
,
1343 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1347 printf("\n%u unit files listed.\n", c
);
1350 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1351 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1352 _cleanup_free_ UnitFileList
*units
= NULL
;
1360 pager_open(arg_no_pager
, false);
1362 if (install_client_side()) {
1368 h
= hashmap_new(&string_hash_ops
);
1372 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1374 unit_file_list_free(h
);
1375 return log_error_errno(r
, "Failed to get unit file list: %m");
1378 n_units
= hashmap_size(h
);
1380 units
= new(UnitFileList
, n_units
);
1381 if (!units
&& n_units
> 0) {
1382 unit_file_list_free(h
);
1386 HASHMAP_FOREACH(u
, h
, i
) {
1387 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1394 assert(c
<= n_units
);
1397 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1400 r
= acquire_bus(BUS_MANAGER
, &bus
);
1404 r
= sd_bus_call_method(
1406 "org.freedesktop.systemd1",
1407 "/org/freedesktop/systemd1",
1408 "org.freedesktop.systemd1.Manager",
1414 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1416 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1418 return bus_log_parse_error(r
);
1420 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1422 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1425 units
[c
] = (struct UnitFileList
) {
1427 unit_file_state_from_string(state
)
1430 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1435 return bus_log_parse_error(r
);
1437 r
= sd_bus_message_exit_container(reply
);
1439 return bus_log_parse_error(r
);
1442 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1443 output_unit_file_list(units
, c
);
1445 if (install_client_side()) {
1446 for (unit
= units
; unit
< units
+ c
; unit
++)
1453 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1454 _cleanup_free_
char *n
= NULL
;
1455 size_t max_len
= MAX(columns(),20u);
1461 for (i
= level
- 1; i
>= 0; i
--) {
1463 if (len
> max_len
- 3 && !arg_full
) {
1464 printf("%s...\n",max_len
% 2 ? "" : " ");
1467 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1471 if (len
> max_len
- 3 && !arg_full
) {
1472 printf("%s...\n",max_len
% 2 ? "" : " ");
1476 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1480 printf("%s\n", name
);
1484 n
= ellipsize(name
, max_len
-len
, 100);
1492 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1494 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1495 [DEPENDENCY_FORWARD
] = "Requires\0"
1500 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1505 [DEPENDENCY_AFTER
] = "After\0",
1506 [DEPENDENCY_BEFORE
] = "Before\0",
1509 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1510 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1511 _cleanup_strv_free_
char **ret
= NULL
;
1512 _cleanup_free_
char *path
= NULL
;
1518 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1520 path
= unit_dbus_path_from_name(name
);
1524 r
= sd_bus_call_method(
1526 "org.freedesktop.systemd1",
1528 "org.freedesktop.DBus.Properties",
1532 "s", "org.freedesktop.systemd1.Unit");
1534 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1536 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1538 return bus_log_parse_error(r
);
1540 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1543 r
= sd_bus_message_read(reply
, "s", &prop
);
1545 return bus_log_parse_error(r
);
1547 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1548 r
= sd_bus_message_skip(reply
, "v");
1550 return bus_log_parse_error(r
);
1553 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1555 return bus_log_parse_error(r
);
1557 r
= bus_message_read_strv_extend(reply
, &ret
);
1559 return bus_log_parse_error(r
);
1561 r
= sd_bus_message_exit_container(reply
);
1563 return bus_log_parse_error(r
);
1566 r
= sd_bus_message_exit_container(reply
);
1568 return bus_log_parse_error(r
);
1572 return bus_log_parse_error(r
);
1574 r
= sd_bus_message_exit_container(reply
);
1576 return bus_log_parse_error(r
);
1584 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1585 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1587 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1589 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1592 return strcasecmp(*a
, *b
);
1595 static int list_dependencies_one(
1600 unsigned int branches
) {
1602 _cleanup_strv_free_
char **deps
= NULL
;
1610 r
= strv_extend(units
, name
);
1614 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1618 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1620 STRV_FOREACH(c
, deps
) {
1621 if (strv_contains(*units
, *c
)) {
1623 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1636 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1637 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1638 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1641 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1645 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1646 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1653 strv_remove(*units
, name
);
1658 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1659 _cleanup_strv_free_
char **units
= NULL
;
1660 _cleanup_free_
char *unit
= NULL
;
1666 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1668 return log_error_errno(r
, "Failed to mangle unit name: %m");
1672 u
= SPECIAL_DEFAULT_TARGET
;
1674 pager_open(arg_no_pager
, false);
1676 r
= acquire_bus(BUS_MANAGER
, &bus
);
1682 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1685 struct machine_info
{
1689 char *control_group
;
1690 uint32_t n_failed_units
;
1695 static const struct bus_properties_map machine_info_property_map
[] = {
1696 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1697 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1698 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1699 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1700 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1704 static void machine_info_clear(struct machine_info
*info
) {
1708 free(info
->control_group
);
1713 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1719 for (i
= 0; i
< n
; i
++)
1720 machine_info_clear(&machine_infos
[i
]);
1722 free(machine_infos
);
1725 static int compare_machine_info(const void *a
, const void *b
) {
1726 const struct machine_info
*u
= a
, *v
= b
;
1728 if (u
->is_host
!= v
->is_host
)
1729 return u
->is_host
> v
->is_host
? -1 : 1;
1731 return strcasecmp(u
->name
, v
->name
);
1734 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1735 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1741 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1748 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1755 static bool output_show_machine(const char *name
, char **patterns
) {
1756 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1759 static int get_machine_list(
1761 struct machine_info
**_machine_infos
,
1764 struct machine_info
*machine_infos
= NULL
;
1765 _cleanup_strv_free_
char **m
= NULL
;
1766 _cleanup_free_
char *hn
= NULL
;
1771 hn
= gethostname_malloc();
1775 if (output_show_machine(hn
, patterns
)) {
1776 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1779 machine_infos
[c
].is_host
= true;
1780 machine_infos
[c
].name
= hn
;
1783 get_machine_properties(bus
, &machine_infos
[c
]);
1787 r
= sd_get_machine_names(&m
);
1789 return log_error_errno(r
, "Failed to get machine list: %m");
1791 STRV_FOREACH(i
, m
) {
1792 _cleanup_free_
char *class = NULL
;
1794 if (!output_show_machine(*i
, patterns
))
1797 sd_machine_get_class(*i
, &class);
1798 if (!streq_ptr(class, "container"))
1801 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1802 free_machines_list(machine_infos
, c
);
1806 machine_infos
[c
].is_host
= false;
1807 machine_infos
[c
].name
= strdup(*i
);
1808 if (!machine_infos
[c
].name
) {
1809 free_machines_list(machine_infos
, c
);
1813 get_machine_properties(NULL
, &machine_infos
[c
]);
1817 *_machine_infos
= machine_infos
;
1821 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1822 struct machine_info
*m
;
1825 namelen
= sizeof("NAME") - 1,
1826 statelen
= sizeof("STATE") - 1,
1827 failedlen
= sizeof("FAILED") - 1,
1828 jobslen
= sizeof("JOBS") - 1;
1830 assert(machine_infos
|| n
== 0);
1832 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1833 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1834 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1835 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1836 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1838 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1842 if (!arg_no_legend
) {
1846 printf("%-*s %-*s %-*s %-*s\n",
1849 failedlen
, "FAILED",
1853 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1854 const char *on_state
= "", *off_state
= "";
1855 const char *on_failed
= "", *off_failed
= "";
1856 bool circle
= false;
1858 if (streq_ptr(m
->state
, "degraded")) {
1859 on_state
= ansi_highlight_red();
1860 off_state
= ansi_normal();
1862 } else if (!streq_ptr(m
->state
, "running")) {
1863 on_state
= ansi_highlight_yellow();
1864 off_state
= ansi_normal();
1868 if (m
->n_failed_units
> 0) {
1869 on_failed
= ansi_highlight_red();
1870 off_failed
= ansi_normal();
1872 on_failed
= off_failed
= "";
1875 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1878 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1879 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1880 on_state
, statelen
, strna(m
->state
), off_state
,
1881 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1882 jobslen
, m
->n_jobs
);
1884 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1885 namelen
, strna(m
->name
),
1886 on_state
, statelen
, strna(m
->state
), off_state
,
1887 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1888 jobslen
, m
->n_jobs
);
1892 printf("\n%u machines listed.\n", n
);
1895 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1896 struct machine_info
*machine_infos
= NULL
;
1900 if (geteuid() != 0) {
1901 log_error("Must be root.");
1905 pager_open(arg_no_pager
, false);
1907 r
= acquire_bus(BUS_MANAGER
, &bus
);
1911 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1915 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1916 output_machines_list(machine_infos
, r
);
1917 free_machines_list(machine_infos
, r
);
1922 static int get_default(int argc
, char *argv
[], void *userdata
) {
1923 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1924 _cleanup_free_
char *_path
= NULL
;
1928 if (install_client_side()) {
1929 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1931 return log_error_errno(r
, "Failed to get default target: %m");
1935 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1938 r
= acquire_bus(BUS_MANAGER
, &bus
);
1942 r
= sd_bus_call_method(
1944 "org.freedesktop.systemd1",
1945 "/org/freedesktop/systemd1",
1946 "org.freedesktop.systemd1.Manager",
1952 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1954 r
= sd_bus_message_read(reply
, "s", &path
);
1956 return bus_log_parse_error(r
);
1960 printf("%s\n", path
);
1965 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1968 assert(changes
|| n_changes
== 0);
1970 for (i
= 0; i
< n_changes
; i
++) {
1971 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1972 log_info("Created symlink %s, pointing to %s.", changes
[i
].path
, changes
[i
].source
);
1974 log_info("Removed symlink %s.", changes
[i
].path
);
1978 static int set_default(int argc
, char *argv
[], void *userdata
) {
1979 _cleanup_free_
char *unit
= NULL
;
1985 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1987 return log_error_errno(r
, "Failed to mangle unit name: %m");
1989 if (install_client_side()) {
1990 UnitFileChange
*changes
= NULL
;
1991 unsigned n_changes
= 0;
1993 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1995 return log_error_errno(r
, "Failed to set default target: %m");
1998 dump_unit_file_changes(changes
, n_changes
);
2000 unit_file_changes_free(changes
, n_changes
);
2003 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2004 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2007 polkit_agent_open_if_enabled();
2009 r
= acquire_bus(BUS_MANAGER
, &bus
);
2013 r
= sd_bus_call_method(
2015 "org.freedesktop.systemd1",
2016 "/org/freedesktop/systemd1",
2017 "org.freedesktop.systemd1.Manager",
2023 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2025 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2029 /* Try to reload if enabled */
2031 r
= daemon_reload(argc
, argv
, userdata
);
2041 const char *name
, *type
, *state
;
2044 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2045 unsigned id_len
, unit_len
, type_len
, state_len
;
2046 const struct job_info
*j
;
2047 const char *on
, *off
;
2048 bool shorten
= false;
2050 assert(n
== 0 || jobs
);
2053 if (!arg_no_legend
) {
2054 on
= ansi_highlight_green();
2055 off
= ansi_normal();
2057 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2062 pager_open(arg_no_pager
, false);
2064 id_len
= strlen("JOB");
2065 unit_len
= strlen("UNIT");
2066 type_len
= strlen("TYPE");
2067 state_len
= strlen("STATE");
2069 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2070 uint32_t id
= j
->id
;
2071 assert(j
->name
&& j
->type
&& j
->state
);
2073 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2074 unit_len
= MAX(unit_len
, strlen(j
->name
));
2075 type_len
= MAX(type_len
, strlen(j
->type
));
2076 state_len
= MAX(state_len
, strlen(j
->state
));
2079 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2080 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2085 printf("%*s %-*s %-*s %-*s\n",
2089 state_len
, "STATE");
2091 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2092 _cleanup_free_
char *e
= NULL
;
2094 if (streq(j
->state
, "running")) {
2095 on
= ansi_highlight();
2096 off
= ansi_normal();
2100 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2101 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2103 on
, unit_len
, e
? e
: j
->name
, off
,
2105 on
, state_len
, j
->state
, off
);
2108 if (!arg_no_legend
) {
2109 on
= ansi_highlight();
2110 off
= ansi_normal();
2112 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2116 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2117 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2120 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2121 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2122 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2123 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2124 _cleanup_free_
struct job_info
*jobs
= NULL
;
2130 bool skipped
= false;
2132 pager_open(arg_no_pager
, false);
2134 r
= acquire_bus(BUS_MANAGER
, &bus
);
2138 r
= sd_bus_call_method(
2140 "org.freedesktop.systemd1",
2141 "/org/freedesktop/systemd1",
2142 "org.freedesktop.systemd1.Manager",
2148 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2150 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2152 return bus_log_parse_error(r
);
2154 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2155 struct job_info job
= { id
, name
, type
, state
};
2157 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2162 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2168 return bus_log_parse_error(r
);
2170 r
= sd_bus_message_exit_container(reply
);
2172 return bus_log_parse_error(r
);
2174 output_jobs_list(jobs
, c
, skipped
);
2178 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2184 return daemon_reload(argc
, argv
, userdata
);
2186 polkit_agent_open_if_enabled();
2188 r
= acquire_bus(BUS_MANAGER
, &bus
);
2192 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2193 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2197 q
= safe_atou32(*name
, &id
);
2199 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2201 q
= sd_bus_call_method(
2203 "org.freedesktop.systemd1",
2204 "/org/freedesktop/systemd1",
2205 "org.freedesktop.systemd1.Manager",
2211 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2220 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2221 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2225 /* We ignore all errors here, since this is used to show a
2228 /* We don't use unit_dbus_path_from_name() directly since we
2229 * don't want to load the unit if it isn't loaded. */
2231 r
= sd_bus_call_method(
2233 "org.freedesktop.systemd1",
2234 "/org/freedesktop/systemd1",
2235 "org.freedesktop.systemd1.Manager",
2243 r
= sd_bus_message_read(reply
, "o", &path
);
2247 r
= sd_bus_get_property_trivial(
2249 "org.freedesktop.systemd1",
2251 "org.freedesktop.systemd1.Unit",
2261 static void warn_unit_file_changed(const char *name
) {
2262 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2263 ansi_highlight_red(),
2266 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2269 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2276 STRV_FOREACH(p
, lp
->unit_path
) {
2277 _cleanup_free_
char *path
;
2279 path
= path_join(arg_root
, *p
, unit_name
);
2283 if (access(path
, F_OK
) == 0) {
2293 static int unit_find_paths(
2295 const char *unit_name
,
2297 char **fragment_path
,
2298 char ***dropin_paths
) {
2300 _cleanup_free_
char *path
= NULL
;
2301 _cleanup_strv_free_
char **dropins
= NULL
;
2305 * Finds where the unit is defined on disk. Returns 0 if the unit
2306 * is not found. Returns 1 if it is found, and sets
2307 * - the path to the unit in *path, if it exists on disk,
2308 * - and a strv of existing drop-ins in *dropins,
2309 * if the arg is not NULL and any dropins were found.
2313 assert(fragment_path
);
2316 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2317 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2318 _cleanup_free_
char *unit
= NULL
;
2320 unit
= unit_dbus_path_from_name(unit_name
);
2324 r
= sd_bus_get_property_string(
2326 "org.freedesktop.systemd1",
2328 "org.freedesktop.systemd1.Unit",
2333 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2336 r
= sd_bus_get_property_strv(
2338 "org.freedesktop.systemd1",
2340 "org.freedesktop.systemd1.Unit",
2345 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2348 _cleanup_set_free_ Set
*names
;
2350 names
= set_new(NULL
);
2354 r
= set_put(names
, unit_name
);
2356 return log_error_errno(r
, "Failed to add unit name: %m");
2358 r
= unit_file_find_path(lp
, unit_name
, &path
);
2363 _cleanup_free_
char *template = NULL
;
2365 r
= unit_name_template(unit_name
, &template);
2366 if (r
< 0 && r
!= -EINVAL
)
2367 return log_error_errno(r
, "Failed to determine template name: %m");
2369 r
= unit_file_find_path(lp
, template, &path
);
2376 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2384 if (!isempty(path
)) {
2385 *fragment_path
= path
;
2390 if (dropin_paths
&& !strv_isempty(dropins
)) {
2391 *dropin_paths
= dropins
;
2397 log_error("No files found for %s.", unit_name
);
2402 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2403 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2404 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2405 _cleanup_free_
char *buf
= NULL
;
2406 const char *path
, *state
;
2411 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2414 r
= sd_bus_call_method(
2416 "org.freedesktop.systemd1",
2417 "/org/freedesktop/systemd1",
2418 "org.freedesktop.systemd1.Manager",
2424 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2425 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2427 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2428 * considered inactive. */
2432 r
= sd_bus_message_read(reply
, "o", &path
);
2434 return bus_log_parse_error(r
);
2436 r
= sd_bus_get_property_string(
2438 "org.freedesktop.systemd1",
2440 "org.freedesktop.systemd1.Unit",
2445 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2453 return nulstr_contains(good_states
, state
);
2456 static int check_triggering_units(
2460 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2461 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2462 _cleanup_strv_free_
char **triggered_by
= NULL
;
2463 bool print_warning_label
= true;
2467 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2469 return log_error_errno(r
, "Failed to mangle unit name: %m");
2471 path
= unit_dbus_path_from_name(n
);
2475 r
= sd_bus_get_property_string(
2477 "org.freedesktop.systemd1",
2479 "org.freedesktop.systemd1.Unit",
2484 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2486 if (streq(state
, "masked"))
2489 r
= sd_bus_get_property_strv(
2491 "org.freedesktop.systemd1",
2493 "org.freedesktop.systemd1.Unit",
2498 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2500 STRV_FOREACH(i
, triggered_by
) {
2501 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2503 return log_error_errno(r
, "Failed to check unit: %m");
2508 if (print_warning_label
) {
2509 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2510 print_warning_label
= false;
2513 log_warning(" %s", *i
);
2519 static const struct {
2522 } unit_actions
[] = {
2523 { "start", "StartUnit" },
2524 { "stop", "StopUnit" },
2525 { "condstop", "StopUnit" },
2526 { "reload", "ReloadUnit" },
2527 { "restart", "RestartUnit" },
2528 { "try-restart", "TryRestartUnit" },
2529 { "condrestart", "TryRestartUnit" },
2530 { "reload-or-restart", "ReloadOrRestartUnit" },
2531 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2532 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2533 { "condreload", "ReloadOrTryRestartUnit" },
2534 { "force-reload", "ReloadOrTryRestartUnit" }
2537 static const char *verb_to_method(const char *verb
) {
2540 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2541 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2542 return unit_actions
[i
].method
;
2547 static const char *method_to_verb(const char *method
) {
2550 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2551 if (streq_ptr(unit_actions
[i
].method
, method
))
2552 return unit_actions
[i
].verb
;
2557 static int start_unit_one(
2562 sd_bus_error
*error
,
2563 BusWaitForJobs
*w
) {
2565 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2574 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2576 r
= sd_bus_call_method(
2578 "org.freedesktop.systemd1",
2579 "/org/freedesktop/systemd1",
2580 "org.freedesktop.systemd1.Manager",
2588 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2589 /* There's always a fallback possible for
2590 * legacy actions. */
2591 return -EADDRNOTAVAIL
;
2593 verb
= method_to_verb(method
);
2595 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2597 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2598 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2599 log_error("See system logs and 'systemctl status %s' for details.", name
);
2604 r
= sd_bus_message_read(reply
, "o", &path
);
2606 return bus_log_parse_error(r
);
2608 if (need_daemon_reload(bus
, name
) > 0)
2609 warn_unit_file_changed(name
);
2612 log_debug("Adding %s to the set", path
);
2613 r
= bus_wait_for_jobs_add(w
, path
);
2621 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2622 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2629 STRV_FOREACH(name
, names
) {
2633 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2635 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2637 return log_error_errno(r
, "Failed to mangle name: %m");
2639 if (string_is_glob(t
))
2640 r
= strv_consume(&globs
, t
);
2642 r
= strv_consume(&mangled
, t
);
2647 /* Query the manager only if any of the names are a glob, since
2648 * this is fairly expensive */
2649 if (!strv_isempty(globs
)) {
2650 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2651 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2652 size_t allocated
, n
;
2654 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2658 n
= strv_length(mangled
);
2661 for (i
= 0; i
< r
; i
++) {
2662 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2665 mangled
[n
] = strdup(unit_infos
[i
].id
);
2669 mangled
[++n
] = NULL
;
2674 mangled
= NULL
; /* do not free */
2679 static const struct {
2683 } action_table
[_ACTION_MAX
] = {
2684 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2685 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2686 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2687 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2688 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2689 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2690 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2691 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2692 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2693 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2694 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2695 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2696 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2697 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2698 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2701 static enum action
verb_to_action(const char *verb
) {
2704 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2705 if (streq_ptr(action_table
[i
].verb
, verb
))
2708 return _ACTION_INVALID
;
2711 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2712 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2713 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2714 _cleanup_strv_free_
char **names
= NULL
;
2719 ask_password_agent_open_if_enabled();
2720 polkit_agent_open_if_enabled();
2722 r
= acquire_bus(BUS_MANAGER
, &bus
);
2726 if (arg_action
== ACTION_SYSTEMCTL
) {
2729 method
= verb_to_method(argv
[0]);
2730 action
= verb_to_action(argv
[0]);
2732 if (streq(argv
[0], "isolate")) {
2736 mode
= action_table
[action
].mode
?: arg_job_mode
;
2738 one_name
= action_table
[action
].target
;
2740 assert(arg_action
< ELEMENTSOF(action_table
));
2741 assert(action_table
[arg_action
].target
);
2743 method
= "StartUnit";
2745 mode
= action_table
[arg_action
].mode
;
2746 one_name
= action_table
[arg_action
].target
;
2750 names
= strv_new(one_name
, NULL
);
2752 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2754 return log_error_errno(r
, "Failed to expand names: %m");
2757 if (!arg_no_block
) {
2758 r
= bus_wait_for_jobs_new(bus
, &w
);
2760 return log_error_errno(r
, "Could not watch jobs: %m");
2763 STRV_FOREACH(name
, names
) {
2764 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2767 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2768 if (r
>= 0 && q
< 0)
2769 r
= translate_bus_error_to_exit_status(q
, &error
);
2772 if (!arg_no_block
) {
2773 int q
, arg_count
= 0;
2774 const char* extra_args
[4] = {};
2776 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2777 extra_args
[arg_count
++] = "--user";
2779 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2780 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2781 extra_args
[arg_count
++] = "-H";
2782 extra_args
[arg_count
++] = arg_host
;
2783 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2784 extra_args
[arg_count
++] = "-M";
2785 extra_args
[arg_count
++] = arg_host
;
2788 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2792 /* When stopping units, warn if they can still be triggered by
2793 * another active unit (socket, path, timer) */
2794 if (!arg_quiet
&& streq(method
, "StopUnit"))
2795 STRV_FOREACH(name
, names
)
2796 check_triggering_units(bus
, *name
);
2802 static int logind_set_wall_message(void) {
2804 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2806 _cleanup_free_
char *m
= NULL
;
2809 r
= acquire_bus(BUS_FULL
, &bus
);
2813 m
= strv_join(arg_wall
, " ");
2817 r
= sd_bus_call_method(
2819 "org.freedesktop.login1",
2820 "/org/freedesktop/login1",
2821 "org.freedesktop.login1.Manager",
2830 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2836 /* Ask systemd-logind, which might grant access to unprivileged users
2837 * through PolicyKit */
2838 static int logind_reboot(enum action a
) {
2840 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2841 const char *method
, *description
;
2845 polkit_agent_open_if_enabled();
2846 (void) logind_set_wall_message();
2848 r
= acquire_bus(BUS_FULL
, &bus
);
2856 description
= "reboot system";
2859 case ACTION_POWEROFF
:
2860 method
= "PowerOff";
2861 description
= "power off system";
2864 case ACTION_SUSPEND
:
2866 description
= "suspend system";
2869 case ACTION_HIBERNATE
:
2870 method
= "Hibernate";
2871 description
= "hibernate system";
2874 case ACTION_HYBRID_SLEEP
:
2875 method
= "HybridSleep";
2876 description
= "put system into hybrid sleep";
2883 r
= sd_bus_call_method(
2885 "org.freedesktop.login1",
2886 "/org/freedesktop/login1",
2887 "org.freedesktop.login1.Manager",
2891 "b", arg_ask_password
);
2893 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2901 static int logind_check_inhibitors(enum action a
) {
2903 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2904 _cleanup_strv_free_
char **sessions
= NULL
;
2905 const char *what
, *who
, *why
, *mode
;
2912 if (arg_ignore_inhibitors
|| arg_force
> 0)
2924 r
= acquire_bus(BUS_FULL
, &bus
);
2928 r
= sd_bus_call_method(
2930 "org.freedesktop.login1",
2931 "/org/freedesktop/login1",
2932 "org.freedesktop.login1.Manager",
2938 /* If logind is not around, then there are no inhibitors... */
2941 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2943 return bus_log_parse_error(r
);
2945 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2946 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2947 _cleanup_strv_free_
char **sv
= NULL
;
2949 if (!streq(mode
, "block"))
2952 sv
= strv_split(what
, ":");
2956 if ((pid_t
) pid
< 0)
2957 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2959 if (!strv_contains(sv
,
2964 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2967 get_process_comm(pid
, &comm
);
2968 user
= uid_to_name(uid
);
2970 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2971 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2976 return bus_log_parse_error(r
);
2978 r
= sd_bus_message_exit_container(reply
);
2980 return bus_log_parse_error(r
);
2982 /* Check for current sessions */
2983 sd_get_sessions(&sessions
);
2984 STRV_FOREACH(s
, sessions
) {
2985 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2987 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2990 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2993 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2996 sd_session_get_tty(*s
, &tty
);
2997 sd_session_get_seat(*s
, &seat
);
2998 sd_session_get_service(*s
, &service
);
2999 user
= uid_to_name(uid
);
3001 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3008 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3009 action_table
[a
].verb
);
3017 static int logind_prepare_firmware_setup(void) {
3019 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3023 r
= acquire_bus(BUS_FULL
, &bus
);
3027 r
= sd_bus_call_method(
3029 "org.freedesktop.login1",
3030 "/org/freedesktop/login1",
3031 "org.freedesktop.login1.Manager",
3032 "SetRebootToFirmwareSetup",
3037 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3041 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3046 static int prepare_firmware_setup(void) {
3049 if (!arg_firmware_setup
)
3052 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3054 r
= efi_set_reboot_to_firmware(true);
3056 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3061 return logind_prepare_firmware_setup();
3064 static int set_exit_code(uint8_t code
) {
3065 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3069 r
= acquire_bus(BUS_MANAGER
, &bus
);
3073 r
= sd_bus_call_method(
3075 "org.freedesktop.systemd1",
3076 "/org/freedesktop/systemd1",
3077 "org.freedesktop.systemd1.Manager",
3083 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3088 static int start_special(int argc
, char *argv
[], void *userdata
) {
3094 a
= verb_to_action(argv
[0]);
3096 r
= logind_check_inhibitors(a
);
3100 if (arg_force
>= 2 && geteuid() != 0) {
3101 log_error("Must be root.");
3105 r
= prepare_firmware_setup();
3109 if (a
== ACTION_REBOOT
&& argc
> 1) {
3110 r
= update_reboot_param_file(argv
[1]);
3114 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3117 /* If the exit code is not given on the command line,
3118 * don't reset it to zero: just keep it as it might
3119 * have been set previously. */
3121 r
= safe_atou8(argv
[1], &code
);
3123 return log_error_errno(r
, "Invalid exit code.");
3125 r
= set_exit_code(code
);
3130 if (arg_force
>= 2 &&
3137 if (arg_force
>= 1 &&
3144 return daemon_reload(argc
, argv
, userdata
);
3146 /* First try logind, to allow authentication with polkit */
3152 ACTION_HYBRID_SLEEP
)) {
3153 r
= logind_reboot(a
);
3156 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3157 /* requested operation is not supported or already in progress */
3160 /* On all other errors, try low-level operation */
3163 return start_unit(argc
, argv
, userdata
);
3166 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3167 _cleanup_strv_free_
char **names
= NULL
;
3173 r
= acquire_bus(BUS_MANAGER
, &bus
);
3177 r
= expand_names(bus
, args
, NULL
, &names
);
3179 return log_error_errno(r
, "Failed to expand names: %m");
3181 STRV_FOREACH(name
, names
) {
3184 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3191 /* use the given return code for the case that we won't find
3192 * any unit which matches the list */
3193 return found
? 0 : code
;
3196 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3197 /* According to LSB: 3, "program is not running" */
3198 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3201 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3202 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3205 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3206 _cleanup_strv_free_
char **names
= NULL
;
3207 char *kill_who
= NULL
, **name
;
3211 polkit_agent_open_if_enabled();
3213 r
= acquire_bus(BUS_MANAGER
, &bus
);
3218 arg_kill_who
= "all";
3220 /* --fail was specified */
3221 if (streq(arg_job_mode
, "fail"))
3222 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3224 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3226 return log_error_errno(r
, "Failed to expand names: %m");
3228 STRV_FOREACH(name
, names
) {
3229 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3231 q
= sd_bus_call_method(
3233 "org.freedesktop.systemd1",
3234 "/org/freedesktop/systemd1",
3235 "org.freedesktop.systemd1.Manager",
3239 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3241 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3250 typedef struct ExecStatusInfo
{
3258 usec_t start_timestamp
;
3259 usec_t exit_timestamp
;
3264 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3267 static void exec_status_info_free(ExecStatusInfo
*i
) {
3276 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3277 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3280 int32_t code
, status
;
3286 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3288 return bus_log_parse_error(r
);
3292 r
= sd_bus_message_read(m
, "s", &path
);
3294 return bus_log_parse_error(r
);
3296 i
->path
= strdup(path
);
3300 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3302 return bus_log_parse_error(r
);
3304 r
= sd_bus_message_read(m
,
3307 &start_timestamp
, &start_timestamp_monotonic
,
3308 &exit_timestamp
, &exit_timestamp_monotonic
,
3312 return bus_log_parse_error(r
);
3315 i
->start_timestamp
= (usec_t
) start_timestamp
;
3316 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3317 i
->pid
= (pid_t
) pid
;
3321 r
= sd_bus_message_exit_container(m
);
3323 return bus_log_parse_error(r
);
3328 typedef struct UnitStatusInfo
{
3330 const char *load_state
;
3331 const char *active_state
;
3332 const char *sub_state
;
3333 const char *unit_file_state
;
3334 const char *unit_file_preset
;
3336 const char *description
;
3337 const char *following
;
3339 char **documentation
;
3341 const char *fragment_path
;
3342 const char *source_path
;
3343 const char *control_group
;
3345 char **dropin_paths
;
3347 const char *load_error
;
3350 usec_t inactive_exit_timestamp
;
3351 usec_t inactive_exit_timestamp_monotonic
;
3352 usec_t active_enter_timestamp
;
3353 usec_t active_exit_timestamp
;
3354 usec_t inactive_enter_timestamp
;
3356 bool need_daemon_reload
;
3362 const char *status_text
;
3363 const char *pid_file
;
3367 usec_t start_timestamp
;
3368 usec_t exit_timestamp
;
3370 int exit_code
, exit_status
;
3372 usec_t condition_timestamp
;
3373 bool condition_result
;
3374 bool failed_condition_trigger
;
3375 bool failed_condition_negate
;
3376 const char *failed_condition
;
3377 const char *failed_condition_parameter
;
3379 usec_t assert_timestamp
;
3381 bool failed_assert_trigger
;
3382 bool failed_assert_negate
;
3383 const char *failed_assert
;
3384 const char *failed_assert_parameter
;
3387 unsigned n_accepted
;
3388 unsigned n_connections
;
3391 /* Pairs of type, path */
3395 const char *sysfs_path
;
3397 /* Mount, Automount */
3404 uint64_t memory_current
;
3405 uint64_t memory_limit
;
3406 uint64_t cpu_usage_nsec
;
3407 uint64_t tasks_current
;
3410 LIST_HEAD(ExecStatusInfo
, exec
);
3413 static void print_status_info(
3418 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3420 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3421 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3427 /* This shows pretty information about a unit. See
3428 * print_property() for a low-level property printer */
3430 if (streq_ptr(i
->active_state
, "failed")) {
3431 active_on
= ansi_highlight_red();
3432 active_off
= ansi_normal();
3433 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3434 active_on
= ansi_highlight_green();
3435 active_off
= ansi_normal();
3437 active_on
= active_off
= "";
3439 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3441 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3442 printf(" - %s", i
->description
);
3447 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3449 if (streq_ptr(i
->load_state
, "error")) {
3450 on
= ansi_highlight_red();
3451 off
= ansi_normal();
3455 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3457 if (i
->load_error
!= 0)
3458 printf(" Loaded: %s%s%s (Reason: %s)\n",
3459 on
, strna(i
->load_state
), off
, i
->load_error
);
3460 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3461 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3462 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3463 else if (path
&& !isempty(i
->unit_file_state
))
3464 printf(" Loaded: %s%s%s (%s; %s)\n",
3465 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3467 printf(" Loaded: %s%s%s (%s)\n",
3468 on
, strna(i
->load_state
), off
, path
);
3470 printf(" Loaded: %s%s%s\n",
3471 on
, strna(i
->load_state
), off
);
3474 printf("Transient: yes\n");
3476 if (!strv_isempty(i
->dropin_paths
)) {
3477 _cleanup_free_
char *dir
= NULL
;
3481 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3482 if (! dir
|| last
) {
3483 printf(dir
? " " : " Drop-In: ");
3487 dir
= dirname_malloc(*dropin
);
3493 printf("%s\n %s", dir
,
3494 draw_special_char(DRAW_TREE_RIGHT
));
3497 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3499 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3503 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3505 printf(" Active: %s%s (%s)%s",
3506 active_on
, strna(i
->active_state
), ss
, active_off
);
3508 printf(" Active: %s%s%s",
3509 active_on
, strna(i
->active_state
), active_off
);
3511 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3512 printf(" (Result: %s)", i
->result
);
3514 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3515 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3516 (streq_ptr(i
->active_state
, "inactive") ||
3517 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3518 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3519 i
->active_exit_timestamp
;
3521 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3522 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3525 printf(" since %s; %s\n", s2
, s1
);
3527 printf(" since %s\n", s2
);
3531 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3532 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3533 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3535 printf("Condition: start %scondition failed%s at %s%s%s\n",
3536 ansi_highlight_yellow(), ansi_normal(),
3537 s2
, s1
? "; " : "", strempty(s1
));
3538 if (i
->failed_condition_trigger
)
3539 printf(" none of the trigger conditions were met\n");
3540 else if (i
->failed_condition
)
3541 printf(" %s=%s%s was not met\n",
3542 i
->failed_condition
,
3543 i
->failed_condition_negate
? "!" : "",
3544 i
->failed_condition_parameter
);
3547 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3548 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3549 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3551 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3552 ansi_highlight_red(), ansi_normal(),
3553 s2
, s1
? "; " : "", strempty(s1
));
3554 if (i
->failed_assert_trigger
)
3555 printf(" none of the trigger assertions were met\n");
3556 else if (i
->failed_assert
)
3557 printf(" %s=%s%s was not met\n",
3559 i
->failed_assert_negate
? "!" : "",
3560 i
->failed_assert_parameter
);
3564 printf(" Device: %s\n", i
->sysfs_path
);
3566 printf(" Where: %s\n", i
->where
);
3568 printf(" What: %s\n", i
->what
);
3570 STRV_FOREACH(t
, i
->documentation
)
3571 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3573 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3574 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3577 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3579 LIST_FOREACH(exec
, p
, i
->exec
) {
3580 _cleanup_free_
char *argv
= NULL
;
3583 /* Only show exited processes here */
3587 argv
= strv_join(p
->argv
, " ");
3588 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3590 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3592 on
= ansi_highlight_red();
3593 off
= ansi_normal();
3597 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3599 if (p
->code
== CLD_EXITED
) {
3602 printf("status=%i", p
->status
);
3604 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3609 printf("signal=%s", signal_to_string(p
->status
));
3611 printf(")%s\n", off
);
3613 if (i
->main_pid
== p
->pid
&&
3614 i
->start_timestamp
== p
->start_timestamp
&&
3615 i
->exit_timestamp
== p
->start_timestamp
)
3616 /* Let's not show this twice */
3619 if (p
->pid
== i
->control_pid
)
3623 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3624 if (i
->main_pid
> 0) {
3625 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3628 _cleanup_free_
char *comm
= NULL
;
3629 get_process_comm(i
->main_pid
, &comm
);
3631 printf(" (%s)", comm
);
3632 } else if (i
->exit_code
> 0) {
3633 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3635 if (i
->exit_code
== CLD_EXITED
) {
3638 printf("status=%i", i
->exit_status
);
3640 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3645 printf("signal=%s", signal_to_string(i
->exit_status
));
3649 if (i
->control_pid
> 0)
3653 if (i
->control_pid
> 0) {
3654 _cleanup_free_
char *c
= NULL
;
3656 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3658 get_process_comm(i
->control_pid
, &c
);
3667 printf(" Status: \"%s\"\n", i
->status_text
);
3668 if (i
->status_errno
> 0)
3669 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3671 if (i
->tasks_current
!= (uint64_t) -1) {
3672 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3674 if (i
->tasks_max
!= (uint64_t) -1)
3675 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3680 if (i
->memory_current
!= (uint64_t) -1) {
3681 char buf
[FORMAT_BYTES_MAX
];
3683 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3685 if (i
->memory_limit
!= (uint64_t) -1)
3686 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3691 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3692 char buf
[FORMAT_TIMESPAN_MAX
];
3693 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3696 if (i
->control_group
&&
3697 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3698 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3701 printf(" CGroup: %s\n", i
->control_group
);
3703 if (IN_SET(arg_transport
,
3704 BUS_TRANSPORT_LOCAL
,
3705 BUS_TRANSPORT_MACHINE
)) {
3708 static const char prefix
[] = " ";
3711 if (c
> sizeof(prefix
) - 1)
3712 c
-= sizeof(prefix
) - 1;
3716 if (i
->main_pid
> 0)
3717 extra
[k
++] = i
->main_pid
;
3719 if (i
->control_pid
> 0)
3720 extra
[k
++] = i
->control_pid
;
3722 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3726 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3727 show_journal_by_unit(
3732 i
->inactive_exit_timestamp_monotonic
,
3735 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3736 SD_JOURNAL_LOCAL_ONLY
,
3737 arg_scope
== UNIT_FILE_SYSTEM
,
3740 if (i
->need_daemon_reload
)
3741 warn_unit_file_changed(i
->id
);
3744 static void show_unit_help(UnitStatusInfo
*i
) {
3749 if (!i
->documentation
) {
3750 log_info("Documentation for %s not known.", i
->id
);
3754 STRV_FOREACH(p
, i
->documentation
)
3755 if (startswith(*p
, "man:"))
3756 show_man_page(*p
+ 4, false);
3758 log_info("Can't show: %s", *p
);
3761 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3768 switch (contents
[0]) {
3770 case SD_BUS_TYPE_STRING
: {
3773 r
= sd_bus_message_read(m
, "s", &s
);
3775 return bus_log_parse_error(r
);
3778 if (streq(name
, "Id"))
3780 else if (streq(name
, "LoadState"))
3782 else if (streq(name
, "ActiveState"))
3783 i
->active_state
= s
;
3784 else if (streq(name
, "SubState"))
3786 else if (streq(name
, "Description"))
3788 else if (streq(name
, "FragmentPath"))
3789 i
->fragment_path
= s
;
3790 else if (streq(name
, "SourcePath"))
3793 else if (streq(name
, "DefaultControlGroup")) {
3795 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3797 i
->control_group
= e
;
3800 else if (streq(name
, "ControlGroup"))
3801 i
->control_group
= s
;
3802 else if (streq(name
, "StatusText"))
3804 else if (streq(name
, "PIDFile"))
3806 else if (streq(name
, "SysFSPath"))
3808 else if (streq(name
, "Where"))
3810 else if (streq(name
, "What"))
3812 else if (streq(name
, "Following"))
3814 else if (streq(name
, "UnitFileState"))
3815 i
->unit_file_state
= s
;
3816 else if (streq(name
, "UnitFilePreset"))
3817 i
->unit_file_preset
= s
;
3818 else if (streq(name
, "Result"))
3825 case SD_BUS_TYPE_BOOLEAN
: {
3828 r
= sd_bus_message_read(m
, "b", &b
);
3830 return bus_log_parse_error(r
);
3832 if (streq(name
, "Accept"))
3834 else if (streq(name
, "NeedDaemonReload"))
3835 i
->need_daemon_reload
= b
;
3836 else if (streq(name
, "ConditionResult"))
3837 i
->condition_result
= b
;
3838 else if (streq(name
, "AssertResult"))
3839 i
->assert_result
= b
;
3840 else if (streq(name
, "Transient"))
3846 case SD_BUS_TYPE_UINT32
: {
3849 r
= sd_bus_message_read(m
, "u", &u
);
3851 return bus_log_parse_error(r
);
3853 if (streq(name
, "MainPID")) {
3855 i
->main_pid
= (pid_t
) u
;
3858 } else if (streq(name
, "ControlPID"))
3859 i
->control_pid
= (pid_t
) u
;
3860 else if (streq(name
, "ExecMainPID")) {
3862 i
->main_pid
= (pid_t
) u
;
3863 } else if (streq(name
, "NAccepted"))
3865 else if (streq(name
, "NConnections"))
3866 i
->n_connections
= u
;
3871 case SD_BUS_TYPE_INT32
: {
3874 r
= sd_bus_message_read(m
, "i", &j
);
3876 return bus_log_parse_error(r
);
3878 if (streq(name
, "ExecMainCode"))
3879 i
->exit_code
= (int) j
;
3880 else if (streq(name
, "ExecMainStatus"))
3881 i
->exit_status
= (int) j
;
3882 else if (streq(name
, "StatusErrno"))
3883 i
->status_errno
= (int) j
;
3888 case SD_BUS_TYPE_UINT64
: {
3891 r
= sd_bus_message_read(m
, "t", &u
);
3893 return bus_log_parse_error(r
);
3895 if (streq(name
, "ExecMainStartTimestamp"))
3896 i
->start_timestamp
= (usec_t
) u
;
3897 else if (streq(name
, "ExecMainExitTimestamp"))
3898 i
->exit_timestamp
= (usec_t
) u
;
3899 else if (streq(name
, "ActiveEnterTimestamp"))
3900 i
->active_enter_timestamp
= (usec_t
) u
;
3901 else if (streq(name
, "InactiveEnterTimestamp"))
3902 i
->inactive_enter_timestamp
= (usec_t
) u
;
3903 else if (streq(name
, "InactiveExitTimestamp"))
3904 i
->inactive_exit_timestamp
= (usec_t
) u
;
3905 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3906 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3907 else if (streq(name
, "ActiveExitTimestamp"))
3908 i
->active_exit_timestamp
= (usec_t
) u
;
3909 else if (streq(name
, "ConditionTimestamp"))
3910 i
->condition_timestamp
= (usec_t
) u
;
3911 else if (streq(name
, "AssertTimestamp"))
3912 i
->assert_timestamp
= (usec_t
) u
;
3913 else if (streq(name
, "MemoryCurrent"))
3914 i
->memory_current
= u
;
3915 else if (streq(name
, "MemoryLimit"))
3916 i
->memory_limit
= u
;
3917 else if (streq(name
, "TasksCurrent"))
3918 i
->tasks_current
= u
;
3919 else if (streq(name
, "TasksMax"))
3921 else if (streq(name
, "CPUUsageNSec"))
3922 i
->cpu_usage_nsec
= u
;
3927 case SD_BUS_TYPE_ARRAY
:
3929 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3930 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3932 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3934 return bus_log_parse_error(r
);
3936 info
= new0(ExecStatusInfo
, 1);
3940 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3942 info
->name
= strdup(name
);
3946 LIST_PREPEND(exec
, i
->exec
, info
);
3948 info
= new0(ExecStatusInfo
, 1);
3954 return bus_log_parse_error(r
);
3956 r
= sd_bus_message_exit_container(m
);
3958 return bus_log_parse_error(r
);
3962 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3963 const char *type
, *path
;
3965 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3967 return bus_log_parse_error(r
);
3969 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3971 r
= strv_extend(&i
->listen
, type
);
3975 r
= strv_extend(&i
->listen
, path
);
3980 return bus_log_parse_error(r
);
3982 r
= sd_bus_message_exit_container(m
);
3984 return bus_log_parse_error(r
);
3988 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3990 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3992 return bus_log_parse_error(r
);
3994 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3996 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3998 return bus_log_parse_error(r
);
4000 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4001 const char *cond
, *param
;
4002 int trigger
, negate
;
4005 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4007 return bus_log_parse_error(r
);
4009 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4010 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4011 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4012 i
->failed_condition
= cond
;
4013 i
->failed_condition_trigger
= trigger
;
4014 i
->failed_condition_negate
= negate
;
4015 i
->failed_condition_parameter
= param
;
4019 return bus_log_parse_error(r
);
4021 r
= sd_bus_message_exit_container(m
);
4023 return bus_log_parse_error(r
);
4025 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4026 const char *cond
, *param
;
4027 int trigger
, negate
;
4030 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4032 return bus_log_parse_error(r
);
4034 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4035 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4036 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4037 i
->failed_assert
= cond
;
4038 i
->failed_assert_trigger
= trigger
;
4039 i
->failed_assert_negate
= negate
;
4040 i
->failed_assert_parameter
= param
;
4044 return bus_log_parse_error(r
);
4046 r
= sd_bus_message_exit_container(m
);
4048 return bus_log_parse_error(r
);
4055 case SD_BUS_TYPE_STRUCT_BEGIN
:
4057 if (streq(name
, "LoadError")) {
4058 const char *n
, *message
;
4060 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4062 return bus_log_parse_error(r
);
4064 if (!isempty(message
))
4065 i
->load_error
= message
;
4078 r
= sd_bus_message_skip(m
, contents
);
4080 return bus_log_parse_error(r
);
4085 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4091 /* This is a low-level property printer, see
4092 * print_status_info() for the nicer output */
4094 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4095 /* skip what we didn't read */
4096 r
= sd_bus_message_skip(m
, contents
);
4100 switch (contents
[0]) {
4102 case SD_BUS_TYPE_STRUCT_BEGIN
:
4104 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4107 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4109 return bus_log_parse_error(r
);
4112 printf("%s=%"PRIu32
"\n", name
, u
);
4114 printf("%s=\n", name
);
4118 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4121 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4123 return bus_log_parse_error(r
);
4125 if (arg_all
|| !isempty(s
))
4126 printf("%s=%s\n", name
, s
);
4130 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4131 const char *a
= NULL
, *b
= NULL
;
4133 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4135 return bus_log_parse_error(r
);
4137 if (arg_all
|| !isempty(a
) || !isempty(b
))
4138 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4141 } else if (streq_ptr(name
, "SystemCallFilter")) {
4142 _cleanup_strv_free_
char **l
= NULL
;
4145 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4147 return bus_log_parse_error(r
);
4149 r
= sd_bus_message_read(m
, "b", &whitelist
);
4151 return bus_log_parse_error(r
);
4153 r
= sd_bus_message_read_strv(m
, &l
);
4155 return bus_log_parse_error(r
);
4157 r
= sd_bus_message_exit_container(m
);
4159 return bus_log_parse_error(r
);
4161 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4165 fputs(name
, stdout
);
4171 STRV_FOREACH(i
, l
) {
4179 fputc('\n', stdout
);
4187 case SD_BUS_TYPE_ARRAY
:
4189 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4193 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4195 return bus_log_parse_error(r
);
4197 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4198 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4201 return bus_log_parse_error(r
);
4203 r
= sd_bus_message_exit_container(m
);
4205 return bus_log_parse_error(r
);
4209 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4210 const char *type
, *path
;
4212 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4214 return bus_log_parse_error(r
);
4216 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4217 printf("%s=%s\n", type
, path
);
4219 return bus_log_parse_error(r
);
4221 r
= sd_bus_message_exit_container(m
);
4223 return bus_log_parse_error(r
);
4227 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4228 const char *type
, *path
;
4230 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4232 return bus_log_parse_error(r
);
4234 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4235 printf("Listen%s=%s\n", type
, path
);
4237 return bus_log_parse_error(r
);
4239 r
= sd_bus_message_exit_container(m
);
4241 return bus_log_parse_error(r
);
4245 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4247 uint64_t value
, next_elapse
;
4249 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4251 return bus_log_parse_error(r
);
4253 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4254 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4256 printf("%s={ value=%s ; next_elapse=%s }\n",
4258 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4259 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4262 return bus_log_parse_error(r
);
4264 r
= sd_bus_message_exit_container(m
);
4266 return bus_log_parse_error(r
);
4270 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4271 ExecStatusInfo info
= {};
4273 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4275 return bus_log_parse_error(r
);
4277 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4278 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4279 _cleanup_free_
char *tt
;
4281 tt
= strv_join(info
.argv
, " ");
4283 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }\n",
4287 yes_no(info
.ignore
),
4288 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4289 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4291 sigchld_code_to_string(info
.code
),
4293 info
.code
== CLD_EXITED
? "" : "/",
4294 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4297 strv_free(info
.argv
);
4301 r
= sd_bus_message_exit_container(m
);
4303 return bus_log_parse_error(r
);
4307 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4308 const char *path
, *rwm
;
4310 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4312 return bus_log_parse_error(r
);
4314 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4315 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4317 return bus_log_parse_error(r
);
4319 r
= sd_bus_message_exit_container(m
);
4321 return bus_log_parse_error(r
);
4325 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4329 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4331 return bus_log_parse_error(r
);
4333 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4334 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4336 return bus_log_parse_error(r
);
4338 r
= sd_bus_message_exit_container(m
);
4340 return bus_log_parse_error(r
);
4344 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4348 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4350 return bus_log_parse_error(r
);
4352 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4353 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4355 return bus_log_parse_error(r
);
4357 r
= sd_bus_message_exit_container(m
);
4359 return bus_log_parse_error(r
);
4367 r
= bus_print_property(name
, m
, arg_all
);
4369 return bus_log_parse_error(r
);
4372 r
= sd_bus_message_skip(m
, contents
);
4374 return bus_log_parse_error(r
);
4377 printf("%s=[unprintable]\n", name
);
4383 static int show_one(
4387 bool show_properties
,
4391 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4392 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4393 UnitStatusInfo info
= {
4394 .memory_current
= (uint64_t) -1,
4395 .memory_limit
= (uint64_t) -1,
4396 .cpu_usage_nsec
= (uint64_t) -1,
4397 .tasks_current
= (uint64_t) -1,
4398 .tasks_max
= (uint64_t) -1,
4406 log_debug("Showing one %s", path
);
4408 r
= sd_bus_call_method(
4410 "org.freedesktop.systemd1",
4412 "org.freedesktop.DBus.Properties",
4418 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4420 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4422 return bus_log_parse_error(r
);
4429 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4430 const char *name
, *contents
;
4432 r
= sd_bus_message_read(reply
, "s", &name
);
4434 return bus_log_parse_error(r
);
4436 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4438 return bus_log_parse_error(r
);
4440 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4442 return bus_log_parse_error(r
);
4444 if (show_properties
)
4445 r
= print_property(name
, reply
, contents
);
4447 r
= status_property(name
, reply
, &info
, contents
);
4451 r
= sd_bus_message_exit_container(reply
);
4453 return bus_log_parse_error(r
);
4455 r
= sd_bus_message_exit_container(reply
);
4457 return bus_log_parse_error(r
);
4460 return bus_log_parse_error(r
);
4462 r
= sd_bus_message_exit_container(reply
);
4464 return bus_log_parse_error(r
);
4468 if (!show_properties
) {
4469 if (streq(verb
, "help"))
4470 show_unit_help(&info
);
4472 print_status_info(&info
, ellipsized
);
4475 strv_free(info
.documentation
);
4476 strv_free(info
.dropin_paths
);
4477 strv_free(info
.listen
);
4479 if (!streq_ptr(info
.active_state
, "active") &&
4480 !streq_ptr(info
.active_state
, "reloading") &&
4481 streq(verb
, "status")) {
4482 /* According to LSB: "program not running" */
4483 /* 0: program is running or service is OK
4484 * 1: program is dead and /run PID file exists
4485 * 2: program is dead and /run/lock lock file exists
4486 * 3: program is not running
4487 * 4: program or service status is unknown
4489 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4495 while ((p
= info
.exec
)) {
4496 LIST_REMOVE(exec
, info
.exec
, p
);
4497 exec_status_info_free(p
);
4503 static int get_unit_dbus_path_by_pid(
4508 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4509 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4513 r
= sd_bus_call_method(
4515 "org.freedesktop.systemd1",
4516 "/org/freedesktop/systemd1",
4517 "org.freedesktop.systemd1.Manager",
4523 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4525 r
= sd_bus_message_read(reply
, "o", &u
);
4527 return bus_log_parse_error(r
);
4537 static int show_all(
4540 bool show_properties
,
4544 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4545 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4550 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4554 pager_open(arg_no_pager
, false);
4558 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4560 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4561 _cleanup_free_
char *p
= NULL
;
4563 p
= unit_dbus_path_from_name(u
->id
);
4567 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4570 else if (r
> 0 && ret
== 0)
4577 static int show_system_status(sd_bus
*bus
) {
4578 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4579 _cleanup_free_
char *hn
= NULL
;
4580 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4581 const char *on
, *off
;
4584 hn
= gethostname_malloc();
4588 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4590 return log_error_errno(r
, "Failed to read server status: %m");
4592 if (streq_ptr(mi
.state
, "degraded")) {
4593 on
= ansi_highlight_red();
4594 off
= ansi_normal();
4595 } else if (!streq_ptr(mi
.state
, "running")) {
4596 on
= ansi_highlight_yellow();
4597 off
= ansi_normal();
4601 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4603 printf(" State: %s%s%s\n",
4604 on
, strna(mi
.state
), off
);
4606 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4607 printf(" Failed: %u units\n", mi
.n_failed_units
);
4609 printf(" Since: %s; %s\n",
4610 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4611 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4613 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4614 if (IN_SET(arg_transport
,
4615 BUS_TRANSPORT_LOCAL
,
4616 BUS_TRANSPORT_MACHINE
)) {
4617 static const char prefix
[] = " ";
4621 if (c
> sizeof(prefix
) - 1)
4622 c
-= sizeof(prefix
) - 1;
4626 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4632 static int show(int argc
, char *argv
[], void *userdata
) {
4633 bool show_properties
, show_status
, show_help
, new_line
= false;
4634 bool ellipsized
= false;
4640 show_properties
= streq(argv
[0], "show");
4641 show_status
= streq(argv
[0], "status");
4642 show_help
= streq(argv
[0], "help");
4644 if (show_help
&& argc
<= 1) {
4645 log_error("This command expects one or more unit names. Did you mean --help?");
4649 pager_open(arg_no_pager
, false);
4652 /* Increase max number of open files to 16K if we can, we
4653 * might needs this when browsing journal files, which might
4654 * be split up into many files. */
4655 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4657 r
= acquire_bus(BUS_MANAGER
, &bus
);
4661 /* If no argument is specified inspect the manager itself */
4662 if (show_properties
&& argc
<= 1)
4663 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4665 if (show_status
&& argc
<= 1) {
4667 pager_open(arg_no_pager
, false);
4668 show_system_status(bus
);
4672 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4674 _cleanup_free_
char **patterns
= NULL
;
4677 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4678 _cleanup_free_
char *unit
= NULL
;
4681 if (safe_atou32(*name
, &id
) < 0) {
4682 if (strv_push(&patterns
, *name
) < 0)
4686 } else if (show_properties
) {
4687 /* Interpret as job id */
4688 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4692 /* Interpret as PID */
4693 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4700 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4703 else if (r
> 0 && ret
== 0)
4707 if (!strv_isempty(patterns
)) {
4708 _cleanup_strv_free_
char **names
= NULL
;
4710 r
= expand_names(bus
, patterns
, NULL
, &names
);
4712 return log_error_errno(r
, "Failed to expand names: %m");
4714 STRV_FOREACH(name
, names
) {
4715 _cleanup_free_
char *unit
;
4717 unit
= unit_dbus_path_from_name(*name
);
4721 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4724 else if (r
> 0 && ret
== 0)
4730 if (ellipsized
&& !arg_quiet
)
4731 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4736 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4740 assert(user_runtime
);
4743 if (arg_scope
== UNIT_FILE_USER
) {
4744 r
= user_config_home(user_home
);
4746 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4748 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4750 r
= user_runtime_dir(user_runtime
);
4752 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4754 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4757 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4759 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4764 static int cat_file(const char *filename
, bool newline
) {
4765 _cleanup_close_
int fd
;
4767 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4771 printf("%s%s# %s%s\n",
4772 newline
? "\n" : "",
4773 ansi_highlight_blue(),
4778 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4781 static int cat(int argc
, char *argv
[], void *userdata
) {
4782 _cleanup_free_
char *user_home
= NULL
;
4783 _cleanup_free_
char *user_runtime
= NULL
;
4784 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4785 _cleanup_strv_free_
char **names
= NULL
;
4791 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4792 log_error("Cannot remotely cat units.");
4796 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4800 r
= acquire_bus(BUS_MANAGER
, &bus
);
4804 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4806 return log_error_errno(r
, "Failed to expand names: %m");
4808 pager_open(arg_no_pager
, false);
4810 STRV_FOREACH(name
, names
) {
4811 _cleanup_free_
char *fragment_path
= NULL
;
4812 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4815 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4826 if (fragment_path
) {
4827 r
= cat_file(fragment_path
, false);
4829 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4832 STRV_FOREACH(path
, dropin_paths
) {
4833 r
= cat_file(*path
, path
== dropin_paths
);
4835 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4842 static int set_property(int argc
, char *argv
[], void *userdata
) {
4843 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4844 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4845 _cleanup_free_
char *n
= NULL
;
4850 polkit_agent_open_if_enabled();
4852 r
= acquire_bus(BUS_MANAGER
, &bus
);
4856 r
= sd_bus_message_new_method_call(
4859 "org.freedesktop.systemd1",
4860 "/org/freedesktop/systemd1",
4861 "org.freedesktop.systemd1.Manager",
4862 "SetUnitProperties");
4864 return bus_log_create_error(r
);
4866 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4868 return log_error_errno(r
, "Failed to mangle unit name: %m");
4870 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4872 return bus_log_create_error(r
);
4874 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4876 return bus_log_create_error(r
);
4878 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4879 r
= bus_append_unit_property_assignment(m
, *i
);
4884 r
= sd_bus_message_close_container(m
);
4886 return bus_log_create_error(r
);
4888 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4890 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4895 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4896 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4901 polkit_agent_open_if_enabled();
4903 r
= acquire_bus(BUS_MANAGER
, &bus
);
4907 if (arg_action
== ACTION_RELOAD
)
4909 else if (arg_action
== ACTION_REEXEC
)
4910 method
= "Reexecute";
4912 assert(arg_action
== ACTION_SYSTEMCTL
);
4915 streq(argv
[0], "clear-jobs") ||
4916 streq(argv
[0], "cancel") ? "ClearJobs" :
4917 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4918 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4919 streq(argv
[0], "halt") ? "Halt" :
4920 streq(argv
[0], "poweroff") ? "PowerOff" :
4921 streq(argv
[0], "reboot") ? "Reboot" :
4922 streq(argv
[0], "kexec") ? "KExec" :
4923 streq(argv
[0], "exit") ? "Exit" :
4924 /* "daemon-reload" */ "Reload";
4927 r
= sd_bus_call_method(
4929 "org.freedesktop.systemd1",
4930 "/org/freedesktop/systemd1",
4931 "org.freedesktop.systemd1.Manager",
4936 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4937 /* There's always a fallback possible for
4938 * legacy actions. */
4940 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4941 /* On reexecution, we expect a disconnect, not a
4945 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
4947 return r
< 0 ? r
: 0;
4950 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4951 _cleanup_strv_free_
char **names
= NULL
;
4957 return daemon_reload(argc
, argv
, userdata
);
4959 polkit_agent_open_if_enabled();
4961 r
= acquire_bus(BUS_MANAGER
, &bus
);
4965 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4967 return log_error_errno(r
, "Failed to expand names: %m");
4969 STRV_FOREACH(name
, names
) {
4970 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4972 q
= sd_bus_call_method(
4974 "org.freedesktop.systemd1",
4975 "/org/freedesktop/systemd1",
4976 "org.freedesktop.systemd1.Manager",
4982 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4991 static int show_environment(int argc
, char *argv
[], void *userdata
) {
4992 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4993 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4998 pager_open(arg_no_pager
, false);
5000 r
= acquire_bus(BUS_MANAGER
, &bus
);
5004 r
= sd_bus_get_property(
5006 "org.freedesktop.systemd1",
5007 "/org/freedesktop/systemd1",
5008 "org.freedesktop.systemd1.Manager",
5014 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5016 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5018 return bus_log_parse_error(r
);
5020 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5023 return bus_log_parse_error(r
);
5025 r
= sd_bus_message_exit_container(reply
);
5027 return bus_log_parse_error(r
);
5032 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5033 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5034 _cleanup_free_
char *cmdline_init
= NULL
;
5035 const char *root
, *init
;
5039 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5040 log_error("Cannot switch root remotely.");
5044 if (argc
< 2 || argc
> 3) {
5045 log_error("Wrong number of arguments.");
5054 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5055 "init", &cmdline_init
,
5058 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5060 init
= cmdline_init
;
5067 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5069 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5070 root_init_path
= strjoina(root
, "/", init
);
5072 /* If the passed init is actually the same as the
5073 * systemd binary, then let's suppress it. */
5074 if (files_same(root_init_path
, root_systemd_path
) > 0)
5078 r
= acquire_bus(BUS_MANAGER
, &bus
);
5082 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5084 r
= sd_bus_call_method(
5086 "org.freedesktop.systemd1",
5087 "/org/freedesktop/systemd1",
5088 "org.freedesktop.systemd1.Manager",
5094 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5099 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5100 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5101 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5109 polkit_agent_open_if_enabled();
5111 r
= acquire_bus(BUS_MANAGER
, &bus
);
5115 method
= streq(argv
[0], "set-environment")
5117 : "UnsetEnvironment";
5119 r
= sd_bus_message_new_method_call(
5122 "org.freedesktop.systemd1",
5123 "/org/freedesktop/systemd1",
5124 "org.freedesktop.systemd1.Manager",
5127 return bus_log_create_error(r
);
5129 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5131 return bus_log_create_error(r
);
5133 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5135 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5140 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5141 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5142 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5146 polkit_agent_open_if_enabled();
5148 r
= acquire_bus(BUS_MANAGER
, &bus
);
5152 r
= sd_bus_message_new_method_call(
5155 "org.freedesktop.systemd1",
5156 "/org/freedesktop/systemd1",
5157 "org.freedesktop.systemd1.Manager",
5160 return bus_log_create_error(r
);
5163 r
= sd_bus_message_append_strv(m
, environ
);
5167 r
= sd_bus_message_open_container(m
, 'a', "s");
5169 return bus_log_create_error(r
);
5171 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5173 if (!env_name_is_valid(*a
)) {
5174 log_error("Not a valid environment variable name: %s", *a
);
5178 STRV_FOREACH(b
, environ
) {
5181 eq
= startswith(*b
, *a
);
5182 if (eq
&& *eq
== '=') {
5184 r
= sd_bus_message_append(m
, "s", *b
);
5186 return bus_log_create_error(r
);
5193 r
= sd_bus_message_close_container(m
);
5196 return bus_log_create_error(r
);
5198 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5200 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5205 static int enable_sysv_units(const char *verb
, char **args
) {
5208 #if defined(HAVE_SYSV_COMPAT)
5210 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5212 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5215 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5218 if (!STR_IN_SET(verb
,
5224 /* Processes all SysV units, and reshuffles the array so that
5225 * afterwards only the native units remain */
5227 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5234 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5235 bool found_native
= false, found_sysv
;
5237 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5245 if (!endswith(name
, ".service"))
5248 if (path_is_absolute(name
))
5251 STRV_FOREACH(k
, paths
.unit_path
) {
5252 _cleanup_free_
char *path
= NULL
;
5254 path
= path_join(arg_root
, *k
, name
);
5258 found_native
= access(path
, F_OK
) >= 0;
5263 /* If we have both a native unit and a SysV script,
5264 * enable/disable them both (below); for is-enabled, prefer the
5266 if (found_native
&& streq(verb
, "is-enabled"))
5269 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5273 p
[strlen(p
) - strlen(".service")] = 0;
5274 found_sysv
= access(p
, F_OK
) >= 0;
5279 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5281 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5283 if (!isempty(arg_root
))
5284 argv
[c
++] = q
= strappend("--root=", arg_root
);
5287 argv
[c
++] = basename(p
);
5290 l
= strv_join((char**)argv
, " ");
5294 log_info("Executing %s", l
);
5298 return log_error_errno(errno
, "Failed to fork: %m");
5299 else if (pid
== 0) {
5302 (void) reset_all_signal_handlers();
5303 (void) reset_signal_mask();
5305 execv(argv
[0], (char**) argv
);
5306 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5307 _exit(EXIT_FAILURE
);
5310 j
= wait_for_terminate(pid
, &status
);
5312 log_error_errno(j
, "Failed to wait for child: %m");
5316 if (status
.si_code
== CLD_EXITED
) {
5317 if (streq(verb
, "is-enabled")) {
5318 if (status
.si_status
== 0) {
5327 } else if (status
.si_status
!= 0)
5335 /* Remove this entry, so that we don't try enabling it as native unit */
5338 assert(args
[f
] == name
);
5339 strv_remove(args
, name
);
5346 static int mangle_names(char **original_names
, char ***mangled_names
) {
5347 char **i
, **l
, **name
;
5350 l
= i
= new(char*, strv_length(original_names
) + 1);
5354 STRV_FOREACH(name
, original_names
) {
5356 /* When enabling units qualified path names are OK,
5357 * too, hence allow them explicitly. */
5359 if (is_path(*name
)) {
5366 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5369 return log_error_errno(r
, "Failed to mangle unit name: %m");
5382 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5383 _cleanup_strv_free_
char **names
= NULL
;
5384 const char *verb
= argv
[0];
5385 UnitFileChange
*changes
= NULL
;
5386 unsigned n_changes
= 0;
5387 int carries_install_info
= -1;
5393 r
= mangle_names(strv_skip(argv
, 1), &names
);
5397 r
= enable_sysv_units(verb
, names
);
5401 /* If the operation was fully executed by the SysV compat,
5402 * let's finish early */
5403 if (strv_isempty(names
))
5406 if (install_client_side()) {
5407 if (streq(verb
, "enable")) {
5408 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5409 carries_install_info
= r
;
5410 } else if (streq(verb
, "disable"))
5411 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5412 else if (streq(verb
, "reenable")) {
5413 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5414 carries_install_info
= r
;
5415 } else if (streq(verb
, "link"))
5416 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5417 else if (streq(verb
, "preset")) {
5418 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5419 carries_install_info
= r
;
5420 } else if (streq(verb
, "mask"))
5421 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5422 else if (streq(verb
, "unmask"))
5423 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5425 assert_not_reached("Unknown verb");
5427 if (r
== -ESHUTDOWN
)
5428 return log_error_errno(r
, "Unit file is masked.");
5430 return log_error_errno(r
, "Operation failed: %m");
5433 dump_unit_file_changes(changes
, n_changes
);
5437 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5438 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5439 int expect_carries_install_info
= false;
5440 bool send_force
= true, send_preset_mode
= false;
5444 polkit_agent_open_if_enabled();
5446 r
= acquire_bus(BUS_MANAGER
, &bus
);
5450 if (streq(verb
, "enable")) {
5451 method
= "EnableUnitFiles";
5452 expect_carries_install_info
= true;
5453 } else if (streq(verb
, "disable")) {
5454 method
= "DisableUnitFiles";
5456 } else if (streq(verb
, "reenable")) {
5457 method
= "ReenableUnitFiles";
5458 expect_carries_install_info
= true;
5459 } else if (streq(verb
, "link"))
5460 method
= "LinkUnitFiles";
5461 else if (streq(verb
, "preset")) {
5463 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5464 method
= "PresetUnitFilesWithMode";
5465 send_preset_mode
= true;
5467 method
= "PresetUnitFiles";
5469 expect_carries_install_info
= true;
5470 } else if (streq(verb
, "mask"))
5471 method
= "MaskUnitFiles";
5472 else if (streq(verb
, "unmask")) {
5473 method
= "UnmaskUnitFiles";
5476 assert_not_reached("Unknown verb");
5478 r
= sd_bus_message_new_method_call(
5481 "org.freedesktop.systemd1",
5482 "/org/freedesktop/systemd1",
5483 "org.freedesktop.systemd1.Manager",
5486 return bus_log_create_error(r
);
5488 r
= sd_bus_message_append_strv(m
, names
);
5490 return bus_log_create_error(r
);
5492 if (send_preset_mode
) {
5493 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5495 return bus_log_create_error(r
);
5498 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5500 return bus_log_create_error(r
);
5503 r
= sd_bus_message_append(m
, "b", arg_force
);
5505 return bus_log_create_error(r
);
5508 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5510 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5512 if (expect_carries_install_info
) {
5513 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5515 return bus_log_parse_error(r
);
5518 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5522 /* Try to reload if enabled */
5524 r
= daemon_reload(argc
, argv
, userdata
);
5529 if (carries_install_info
== 0)
5530 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5531 "using systemctl.\n"
5532 "Possible reasons for having this kind of units are:\n"
5533 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5534 " .wants/ or .requires/ directory.\n"
5535 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5536 " a requirement dependency on it.\n"
5537 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5538 " D-Bus, udev, scripted systemctl call, ...).\n");
5540 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5541 char *new_args
[n_changes
+ 2];
5545 r
= acquire_bus(BUS_MANAGER
, &bus
);
5549 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5550 for (i
= 0; i
< n_changes
; i
++)
5551 new_args
[i
+ 1] = basename(changes
[i
].path
);
5552 new_args
[i
+ 1] = NULL
;
5554 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5558 unit_file_changes_free(changes
, n_changes
);
5563 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5564 _cleanup_strv_free_
char **names
= NULL
;
5565 _cleanup_free_
char *target
= NULL
;
5566 const char *verb
= argv
[0];
5573 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5575 return log_error_errno(r
, "Failed to mangle unit name: %m");
5577 r
= mangle_names(strv_skip(argv
, 2), &names
);
5581 if (streq(verb
, "add-wants"))
5583 else if (streq(verb
, "add-requires"))
5584 dep
= UNIT_REQUIRES
;
5586 assert_not_reached("Unknown verb");
5588 if (install_client_side()) {
5589 UnitFileChange
*changes
= NULL
;
5590 unsigned n_changes
= 0;
5592 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5593 if (r
== -ESHUTDOWN
)
5594 return log_error_errno(r
, "Unit file is masked.");
5596 return log_error_errno(r
, "Can't add dependency: %m");
5599 dump_unit_file_changes(changes
, n_changes
);
5601 unit_file_changes_free(changes
, n_changes
);
5604 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5605 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5608 polkit_agent_open_if_enabled();
5610 r
= acquire_bus(BUS_MANAGER
, &bus
);
5614 r
= sd_bus_message_new_method_call(
5617 "org.freedesktop.systemd1",
5618 "/org/freedesktop/systemd1",
5619 "org.freedesktop.systemd1.Manager",
5620 "AddDependencyUnitFiles");
5622 return bus_log_create_error(r
);
5624 r
= sd_bus_message_append_strv(m
, names
);
5626 return bus_log_create_error(r
);
5628 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5630 return bus_log_create_error(r
);
5632 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5634 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5636 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5641 r
= daemon_reload(argc
, argv
, userdata
);
5649 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5650 UnitFileChange
*changes
= NULL
;
5651 unsigned n_changes
= 0;
5654 if (install_client_side()) {
5656 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5658 log_error_errno(r
, "Operation failed: %m");
5663 dump_unit_file_changes(changes
, n_changes
);
5668 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5669 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5672 polkit_agent_open_if_enabled();
5674 r
= acquire_bus(BUS_MANAGER
, &bus
);
5678 r
= sd_bus_call_method(
5680 "org.freedesktop.systemd1",
5681 "/org/freedesktop/systemd1",
5682 "org.freedesktop.systemd1.Manager",
5683 "PresetAllUnitFiles",
5687 unit_file_preset_mode_to_string(arg_preset_mode
),
5691 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5693 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5698 r
= daemon_reload(argc
, argv
, userdata
);
5704 unit_file_changes_free(changes
, n_changes
);
5709 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5711 _cleanup_strv_free_
char **names
= NULL
;
5716 r
= mangle_names(strv_skip(argv
, 1), &names
);
5720 r
= enable_sysv_units(argv
[0], names
);
5726 if (install_client_side()) {
5728 STRV_FOREACH(name
, names
) {
5729 UnitFileState state
;
5731 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5733 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5737 UNIT_FILE_ENABLED_RUNTIME
,
5739 UNIT_FILE_INDIRECT
))
5743 puts(unit_file_state_to_string(state
));
5747 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5750 r
= acquire_bus(BUS_MANAGER
, &bus
);
5754 STRV_FOREACH(name
, names
) {
5755 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5758 r
= sd_bus_call_method(
5760 "org.freedesktop.systemd1",
5761 "/org/freedesktop/systemd1",
5762 "org.freedesktop.systemd1.Manager",
5768 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5770 r
= sd_bus_message_read(reply
, "s", &s
);
5772 return bus_log_parse_error(r
);
5774 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5785 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5786 _cleanup_free_
char *state
= NULL
;
5790 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5793 return EXIT_FAILURE
;
5796 r
= acquire_bus(BUS_MANAGER
, &bus
);
5800 r
= sd_bus_get_property_string(
5802 "org.freedesktop.systemd1",
5803 "/org/freedesktop/systemd1",
5804 "org.freedesktop.systemd1.Manager",
5817 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5820 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5821 _cleanup_free_
char *t
= NULL
;
5825 assert(original_path
);
5828 r
= tempfn_random(new_path
, NULL
, &t
);
5830 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5832 r
= mkdir_parents(new_path
, 0755);
5834 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5836 r
= copy_file(original_path
, t
, 0, 0644, 0);
5841 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5844 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5852 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5853 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5858 switch (arg_scope
) {
5859 case UNIT_FILE_SYSTEM
:
5860 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5862 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5864 case UNIT_FILE_GLOBAL
:
5865 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5867 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5869 case UNIT_FILE_USER
:
5871 assert(user_runtime
);
5873 path
= path_join(arg_root
, user_home
, name
);
5875 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5878 run
= path_join(arg_root
, user_runtime
, name
);
5882 assert_not_reached("Invalid scope");
5884 if (!path
|| (arg_runtime
&& !run
))
5888 if (access(path
, F_OK
) >= 0) {
5889 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5893 if (path2
&& access(path2
, F_OK
) >= 0) {
5894 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5908 static int unit_file_create_dropin(const char *unit_name
, const char *user_home
, const char *user_runtime
, char **ret_new_path
, char **ret_tmp_path
) {
5909 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5913 assert(ret_new_path
);
5914 assert(ret_tmp_path
);
5916 ending
= strjoina(unit_name
, ".d/override.conf");
5917 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5921 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5927 *ret_new_path
= tmp_new_path
;
5928 *ret_tmp_path
= tmp_tmp_path
;
5933 static int unit_file_create_copy(
5934 const char *unit_name
,
5935 const char *fragment_path
,
5936 const char *user_home
,
5937 const char *user_runtime
,
5938 char **ret_new_path
,
5939 char **ret_tmp_path
) {
5941 char *tmp_new_path
, *tmp_tmp_path
;
5944 assert(fragment_path
);
5946 assert(ret_new_path
);
5947 assert(ret_tmp_path
);
5949 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5953 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5956 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5961 if (response
!= 'y') {
5962 log_warning("%s ignored", unit_name
);
5968 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5970 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5975 *ret_new_path
= tmp_new_path
;
5976 *ret_tmp_path
= tmp_tmp_path
;
5981 static int run_editor(char **paths
) {
5989 return log_error_errno(errno
, "Failed to fork: %m");
5993 char *editor
, **editor_args
= NULL
;
5994 char **tmp_path
, **original_path
, *p
;
5995 unsigned n_editor_args
= 0, i
= 1;
5998 (void) reset_all_signal_handlers();
5999 (void) reset_signal_mask();
6001 argc
= strv_length(paths
)/2 + 1;
6003 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6004 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6005 * we try to execute well known editors
6007 editor
= getenv("SYSTEMD_EDITOR");
6009 editor
= getenv("EDITOR");
6011 editor
= getenv("VISUAL");
6013 if (!isempty(editor
)) {
6014 editor_args
= strv_split(editor
, WHITESPACE
);
6017 _exit(EXIT_FAILURE
);
6019 n_editor_args
= strv_length(editor_args
);
6020 argc
+= n_editor_args
- 1;
6022 args
= newa(const char*, argc
+ 1);
6024 if (n_editor_args
> 0) {
6025 args
[0] = editor_args
[0];
6026 for (; i
< n_editor_args
; i
++)
6027 args
[i
] = editor_args
[i
];
6030 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6031 args
[i
] = *tmp_path
;
6036 if (n_editor_args
> 0)
6037 execvp(args
[0], (char* const*) args
);
6039 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6041 execvp(p
, (char* const*) args
);
6042 /* We do not fail if the editor doesn't exist
6043 * because we want to try each one of them before
6046 if (errno
!= ENOENT
) {
6047 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6048 _exit(EXIT_FAILURE
);
6052 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6053 _exit(EXIT_FAILURE
);
6056 r
= wait_for_terminate_and_warn("editor", pid
, true);
6058 return log_error_errno(r
, "Failed to wait for child: %m");
6063 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6064 _cleanup_free_
char *user_home
= NULL
;
6065 _cleanup_free_
char *user_runtime
= NULL
;
6066 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6073 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6077 STRV_FOREACH(name
, names
) {
6078 _cleanup_free_
char *path
= NULL
;
6079 char *new_path
, *tmp_path
;
6081 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6087 // FIXME: support units with path==NULL (no FragmentPath)
6088 log_error("No fragment exists for %s.", *name
);
6093 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6095 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6099 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6107 static int edit(int argc
, char *argv
[], void *userdata
) {
6108 _cleanup_strv_free_
char **names
= NULL
;
6109 _cleanup_strv_free_
char **paths
= NULL
;
6110 char **original
, **tmp
;
6115 log_error("Cannot edit units if not on a tty.");
6119 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6120 log_error("Cannot edit units remotely.");
6124 r
= acquire_bus(BUS_MANAGER
, &bus
);
6128 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6130 return log_error_errno(r
, "Failed to expand names: %m");
6132 r
= find_paths_to_edit(bus
, names
, &paths
);
6136 if (strv_isempty(paths
))
6139 r
= run_editor(paths
);
6143 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6144 /* If the temporary file is empty we ignore it. It's
6145 * useful if the user wants to cancel its modification
6147 if (null_or_empty_path(*tmp
)) {
6148 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6152 r
= rename(*tmp
, *original
);
6154 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6161 if (!arg_no_reload
&& !install_client_side())
6162 r
= daemon_reload(argc
, argv
, userdata
);
6165 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6166 (void) unlink(*tmp
);
6168 /* Removing empty dropin dirs */
6170 _cleanup_free_
char *dir
= dirname_malloc(*original
);
6171 /* no need to check if the dir is empty, rmdir
6172 * does nothing if it is not the case.
6181 static void systemctl_help(void) {
6183 pager_open(arg_no_pager
, false);
6185 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6186 "Query or send control commands to the systemd manager.\n\n"
6187 " -h --help Show this help\n"
6188 " --version Show package version\n"
6189 " --system Connect to system manager\n"
6190 " --user Connect to user service manager\n"
6191 " -H --host=[USER@]HOST\n"
6192 " Operate on remote host\n"
6193 " -M --machine=CONTAINER\n"
6194 " Operate on local container\n"
6195 " -t --type=TYPE List units of a particular type\n"
6196 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6197 " -p --property=NAME Show only properties by this name\n"
6198 " -a --all Show all loaded units/properties, including dead/empty\n"
6199 " ones. To list all units installed on the system, use\n"
6200 " the 'list-unit-files' command instead.\n"
6201 " -l --full Don't ellipsize unit names on output\n"
6202 " -r --recursive Show unit list of host and local containers\n"
6203 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6204 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6205 " queueing a new job\n"
6206 " --show-types When showing sockets, explicitly show their type\n"
6207 " -i --ignore-inhibitors\n"
6208 " When shutting down or sleeping, ignore inhibitors\n"
6209 " --kill-who=WHO Who to send signal to\n"
6210 " -s --signal=SIGNAL Which signal to send\n"
6211 " --now Start or stop unit in addition to enabling or disabling it\n"
6212 " -q --quiet Suppress output\n"
6213 " --no-block Do not wait until operation finished\n"
6214 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6215 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6216 " --no-legend Do not print a legend (column headers and hints)\n"
6217 " --no-pager Do not pipe output into a pager\n"
6218 " --no-ask-password\n"
6219 " Do not ask for system passwords\n"
6220 " --global Enable/disable unit files globally\n"
6221 " --runtime Enable unit files only temporarily until next reboot\n"
6222 " -f --force When enabling unit files, override existing symlinks\n"
6223 " When shutting down, execute action immediately\n"
6224 " --preset-mode= Apply only enable, only disable, or all presets\n"
6225 " --root=PATH Enable unit files in the specified root directory\n"
6226 " -n --lines=INTEGER Number of journal entries to show\n"
6227 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6228 " short-precise, short-monotonic, verbose,\n"
6229 " export, json, json-pretty, json-sse, cat)\n"
6230 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6231 " --plain Print unit dependencies as a list instead of a tree\n\n"
6233 " list-units [PATTERN...] List loaded units\n"
6234 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6235 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6236 " start NAME... Start (activate) one or more units\n"
6237 " stop NAME... Stop (deactivate) one or more units\n"
6238 " reload NAME... Reload one or more units\n"
6239 " restart NAME... Start or restart one or more units\n"
6240 " try-restart NAME... Restart one or more units if active\n"
6241 " reload-or-restart NAME... Reload one or more units if possible,\n"
6242 " otherwise start or restart\n"
6243 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6244 " if supported, otherwise restart\n"
6245 " isolate NAME Start one unit and stop all others\n"
6246 " kill NAME... Send signal to processes of a unit\n"
6247 " is-active PATTERN... Check whether units are active\n"
6248 " is-failed PATTERN... Check whether units are failed\n"
6249 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6250 " show [PATTERN...|JOB...] Show properties of one or more\n"
6251 " units/jobs or the manager\n"
6252 " cat PATTERN... Show files and drop-ins of one or more units\n"
6253 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6254 " help PATTERN...|PID... Show manual for one or more units\n"
6255 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6257 " list-dependencies [NAME] Recursively show units which are required\n"
6258 " or wanted by this unit or by which this\n"
6259 " unit is required or wanted\n\n"
6260 "Unit File Commands:\n"
6261 " list-unit-files [PATTERN...] List installed unit files\n"
6262 " enable NAME... Enable one or more unit files\n"
6263 " disable NAME... Disable one or more unit files\n"
6264 " reenable NAME... Reenable one or more unit files\n"
6265 " preset NAME... Enable/disable one or more unit files\n"
6266 " based on preset configuration\n"
6267 " preset-all Enable/disable all unit files based on\n"
6268 " preset configuration\n"
6269 " is-enabled NAME... Check whether unit files are enabled\n"
6270 " mask NAME... Mask one or more units\n"
6271 " unmask NAME... Unmask one or more units\n"
6272 " link PATH... Link one or more units files into\n"
6273 " the search path\n"
6274 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6275 " on specified one or more units\n"
6276 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6277 " on specified one or more units\n"
6278 " edit NAME... Edit one or more unit files\n"
6279 " get-default Get the name of the default target\n"
6280 " set-default NAME Set the default target\n\n"
6281 "Machine Commands:\n"
6282 " list-machines [PATTERN...] List local containers and host\n\n"
6284 " list-jobs [PATTERN...] List jobs\n"
6285 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6286 "Environment Commands:\n"
6287 " show-environment Dump environment\n"
6288 " set-environment NAME=VALUE... Set one or more environment variables\n"
6289 " unset-environment NAME... Unset one or more environment variables\n"
6290 " import-environment [NAME...] Import all or some environment variables\n\n"
6291 "Manager Lifecycle Commands:\n"
6292 " daemon-reload Reload systemd manager configuration\n"
6293 " daemon-reexec Reexecute systemd manager\n\n"
6294 "System Commands:\n"
6295 " is-system-running Check whether system is fully running\n"
6296 " default Enter system default mode\n"
6297 " rescue Enter system rescue mode\n"
6298 " emergency Enter system emergency mode\n"
6299 " halt Shut down and halt the system\n"
6300 " poweroff Shut down and power-off the system\n"
6301 " reboot [ARG] Shut down and reboot the system\n"
6302 " kexec Shut down and reboot the system with kexec\n"
6303 " exit [EXIT_CODE] Request user instance or container exit\n"
6304 " switch-root ROOT [INIT] Change to a different root file system\n"
6305 " suspend Suspend the system\n"
6306 " hibernate Hibernate the system\n"
6307 " hybrid-sleep Hibernate and suspend the system\n",
6308 program_invocation_short_name
);
6311 static void halt_help(void) {
6312 printf("%s [OPTIONS...]%s\n\n"
6313 "%s the system.\n\n"
6314 " --help Show this help\n"
6315 " --halt Halt the machine\n"
6316 " -p --poweroff Switch off the machine\n"
6317 " --reboot Reboot the machine\n"
6318 " -f --force Force immediate halt/power-off/reboot\n"
6319 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6320 " -d --no-wtmp Don't write wtmp record\n"
6321 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6322 program_invocation_short_name
,
6323 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6324 arg_action
== ACTION_REBOOT
? "Reboot" :
6325 arg_action
== ACTION_POWEROFF
? "Power off" :
6329 static void shutdown_help(void) {
6330 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6331 "Shut down the system.\n\n"
6332 " --help Show this help\n"
6333 " -H --halt Halt the machine\n"
6334 " -P --poweroff Power-off the machine\n"
6335 " -r --reboot Reboot the machine\n"
6336 " -h Equivalent to --poweroff, overridden by --halt\n"
6337 " -k Don't halt/power-off/reboot, just send warnings\n"
6338 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6339 " -c Cancel a pending shutdown\n",
6340 program_invocation_short_name
);
6343 static void telinit_help(void) {
6344 printf("%s [OPTIONS...] {COMMAND}\n\n"
6345 "Send control commands to the init daemon.\n\n"
6346 " --help Show this help\n"
6347 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6349 " 0 Power-off the machine\n"
6350 " 6 Reboot the machine\n"
6351 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6352 " 1, s, S Enter rescue mode\n"
6353 " q, Q Reload init daemon configuration\n"
6354 " u, U Reexecute init daemon\n",
6355 program_invocation_short_name
);
6358 static void runlevel_help(void) {
6359 printf("%s [OPTIONS...]\n\n"
6360 "Prints the previous and current runlevel of the init system.\n\n"
6361 " --help Show this help\n",
6362 program_invocation_short_name
);
6365 static void help_types(void) {
6369 puts("Available unit types:");
6370 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6371 puts(unit_type_to_string(i
));
6374 static void help_states(void) {
6378 puts("Available unit load states:");
6379 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6380 puts(unit_load_state_to_string(i
));
6383 puts("\nAvailable unit active states:");
6384 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6385 puts(unit_active_state_to_string(i
));
6388 puts("\nAvailable automount unit substates:");
6389 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6390 puts(automount_state_to_string(i
));
6393 puts("\nAvailable busname unit substates:");
6394 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6395 puts(busname_state_to_string(i
));
6398 puts("\nAvailable device unit substates:");
6399 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6400 puts(device_state_to_string(i
));
6403 puts("\nAvailable mount unit substates:");
6404 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6405 puts(mount_state_to_string(i
));
6408 puts("\nAvailable path unit substates:");
6409 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6410 puts(path_state_to_string(i
));
6413 puts("\nAvailable scope unit substates:");
6414 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6415 puts(scope_state_to_string(i
));
6418 puts("\nAvailable service unit substates:");
6419 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6420 puts(service_state_to_string(i
));
6423 puts("\nAvailable slice unit substates:");
6424 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6425 puts(slice_state_to_string(i
));
6428 puts("\nAvailable socket unit substates:");
6429 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6430 puts(socket_state_to_string(i
));
6433 puts("\nAvailable swap unit substates:");
6434 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6435 puts(swap_state_to_string(i
));
6438 puts("\nAvailable target unit substates:");
6439 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6440 puts(target_state_to_string(i
));
6443 puts("\nAvailable timer unit substates:");
6444 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6445 puts(timer_state_to_string(i
));
6448 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6457 ARG_IGNORE_DEPENDENCIES
,
6469 ARG_NO_ASK_PASSWORD
,
6482 static const struct option options
[] = {
6483 { "help", no_argument
, NULL
, 'h' },
6484 { "version", no_argument
, NULL
, ARG_VERSION
},
6485 { "type", required_argument
, NULL
, 't' },
6486 { "property", required_argument
, NULL
, 'p' },
6487 { "all", no_argument
, NULL
, 'a' },
6488 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6489 { "after", no_argument
, NULL
, ARG_AFTER
},
6490 { "before", no_argument
, NULL
, ARG_BEFORE
},
6491 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6492 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6493 { "full", no_argument
, NULL
, 'l' },
6494 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6495 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6496 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6497 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6498 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6499 { "user", no_argument
, NULL
, ARG_USER
},
6500 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6501 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6502 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6503 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6504 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6505 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6506 { "quiet", no_argument
, NULL
, 'q' },
6507 { "root", required_argument
, NULL
, ARG_ROOT
},
6508 { "force", no_argument
, NULL
, ARG_FORCE
},
6509 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6510 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6511 { "signal", required_argument
, NULL
, 's' },
6512 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6513 { "host", required_argument
, NULL
, 'H' },
6514 { "machine", required_argument
, NULL
, 'M' },
6515 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6516 { "lines", required_argument
, NULL
, 'n' },
6517 { "output", required_argument
, NULL
, 'o' },
6518 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6519 { "state", required_argument
, NULL
, ARG_STATE
},
6520 { "recursive", no_argument
, NULL
, 'r' },
6521 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6522 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6523 { "now", no_argument
, NULL
, ARG_NOW
},
6524 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6534 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6535 arg_ask_password
= true;
6537 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6549 if (isempty(optarg
)) {
6550 log_error("--type requires arguments.");
6556 _cleanup_free_
char *type
= NULL
;
6558 r
= extract_first_word(&p
, &type
, ",", 0);
6560 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6565 if (streq(type
, "help")) {
6570 if (unit_type_from_string(type
) >= 0) {
6571 if (strv_push(&arg_types
, type
) < 0)
6577 /* It's much nicer to use --state= for
6578 * load states, but let's support this
6579 * in --types= too for compatibility
6580 * with old versions */
6581 if (unit_load_state_from_string(type
) >= 0) {
6582 if (strv_push(&arg_states
, type
) < 0)
6588 log_error("Unknown unit type or load state '%s'.", type
);
6589 log_info("Use -t help to see a list of allowed values.");
6597 /* Make sure that if the empty property list
6598 was specified, we won't show any properties. */
6599 if (isempty(optarg
) && !arg_properties
) {
6600 arg_properties
= new0(char*, 1);
6601 if (!arg_properties
)
6606 _cleanup_free_
char *prop
= NULL
;
6608 r
= extract_first_word(&p
, &prop
, ",", 0);
6610 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6615 if (strv_push(&arg_properties
, prop
) < 0)
6622 /* If the user asked for a particular
6623 * property, show it to him, even if it is
6635 arg_dependency
= DEPENDENCY_REVERSE
;
6639 arg_dependency
= DEPENDENCY_AFTER
;
6643 arg_dependency
= DEPENDENCY_BEFORE
;
6646 case ARG_SHOW_TYPES
:
6647 arg_show_types
= true;
6651 arg_job_mode
= optarg
;
6655 arg_job_mode
= "fail";
6658 case ARG_IRREVERSIBLE
:
6659 arg_job_mode
= "replace-irreversibly";
6662 case ARG_IGNORE_DEPENDENCIES
:
6663 arg_job_mode
= "ignore-dependencies";
6667 arg_scope
= UNIT_FILE_USER
;
6671 arg_scope
= UNIT_FILE_SYSTEM
;
6675 arg_scope
= UNIT_FILE_GLOBAL
;
6679 arg_no_block
= true;
6683 arg_no_legend
= true;
6687 arg_no_pager
= true;
6695 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6705 if (strv_extend(&arg_states
, "failed") < 0)
6723 arg_no_reload
= true;
6727 arg_kill_who
= optarg
;
6731 arg_signal
= signal_from_string_try_harder(optarg
);
6732 if (arg_signal
< 0) {
6733 log_error("Failed to parse signal string %s.", optarg
);
6738 case ARG_NO_ASK_PASSWORD
:
6739 arg_ask_password
= false;
6743 arg_transport
= BUS_TRANSPORT_REMOTE
;
6748 arg_transport
= BUS_TRANSPORT_MACHINE
;
6757 if (safe_atou(optarg
, &arg_lines
) < 0) {
6758 log_error("Failed to parse lines '%s'", optarg
);
6764 arg_output
= output_mode_from_string(optarg
);
6765 if (arg_output
< 0) {
6766 log_error("Unknown output '%s'.", optarg
);
6772 arg_ignore_inhibitors
= true;
6779 case ARG_FIRMWARE_SETUP
:
6780 arg_firmware_setup
= true;
6784 if (isempty(optarg
)) {
6785 log_error("--signal requires arguments.");
6791 _cleanup_free_
char *s
= NULL
;
6793 r
= extract_first_word(&p
, &s
, ",", 0);
6795 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6800 if (streq(s
, "help")) {
6805 if (strv_push(&arg_states
, s
) < 0)
6814 if (geteuid() != 0) {
6815 log_error("--recursive requires root privileges.");
6819 arg_recursive
= true;
6822 case ARG_PRESET_MODE
:
6824 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6825 if (arg_preset_mode
< 0) {
6826 log_error("Failed to parse preset mode: %s.", optarg
);
6837 if (strv_extend(&arg_wall
, optarg
) < 0)
6845 assert_not_reached("Unhandled option");
6848 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6849 log_error("Cannot access user instance remotely.");
6856 static int halt_parse_argv(int argc
, char *argv
[]) {
6865 static const struct option options
[] = {
6866 { "help", no_argument
, NULL
, ARG_HELP
},
6867 { "halt", no_argument
, NULL
, ARG_HALT
},
6868 { "poweroff", no_argument
, NULL
, 'p' },
6869 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6870 { "force", no_argument
, NULL
, 'f' },
6871 { "wtmp-only", no_argument
, NULL
, 'w' },
6872 { "no-wtmp", no_argument
, NULL
, 'd' },
6873 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6882 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6883 if (runlevel
== '0' || runlevel
== '6')
6886 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6894 arg_action
= ACTION_HALT
;
6898 if (arg_action
!= ACTION_REBOOT
)
6899 arg_action
= ACTION_POWEROFF
;
6903 arg_action
= ACTION_REBOOT
;
6925 /* Compatibility nops */
6932 assert_not_reached("Unhandled option");
6935 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6936 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6939 } else if (optind
< argc
) {
6940 log_error("Too many arguments.");
6947 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
6951 if (streq(t
, "now"))
6953 else if (!strchr(t
, ':')) {
6956 if (safe_atou64(t
, &u
) < 0)
6959 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6968 hour
= strtol(t
, &e
, 10);
6969 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6972 minute
= strtol(e
+1, &e
, 10);
6973 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6976 n
= now(CLOCK_REALTIME
);
6977 s
= (time_t) (n
/ USEC_PER_SEC
);
6979 assert_se(localtime_r(&s
, &tm
));
6981 tm
.tm_hour
= (int) hour
;
6982 tm
.tm_min
= (int) minute
;
6985 assert_se(s
= mktime(&tm
));
6987 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6990 *_u
+= USEC_PER_DAY
;
6996 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7003 static const struct option options
[] = {
7004 { "help", no_argument
, NULL
, ARG_HELP
},
7005 { "halt", no_argument
, NULL
, 'H' },
7006 { "poweroff", no_argument
, NULL
, 'P' },
7007 { "reboot", no_argument
, NULL
, 'r' },
7008 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7009 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7019 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7027 arg_action
= ACTION_HALT
;
7031 arg_action
= ACTION_POWEROFF
;
7036 arg_action
= ACTION_KEXEC
;
7038 arg_action
= ACTION_REBOOT
;
7042 arg_action
= ACTION_KEXEC
;
7046 if (arg_action
!= ACTION_HALT
)
7047 arg_action
= ACTION_POWEROFF
;
7062 /* Compatibility nops */
7066 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7073 assert_not_reached("Unhandled option");
7076 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7077 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7079 log_error("Failed to parse time specification: %s", argv
[optind
]);
7083 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7085 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7086 /* No time argument for shutdown cancel */
7087 wall
= argv
+ optind
;
7088 else if (argc
> optind
+ 1)
7089 /* We skip the time argument */
7090 wall
= argv
+ optind
+ 1;
7093 arg_wall
= strv_copy(wall
);
7103 static int telinit_parse_argv(int argc
, char *argv
[]) {
7110 static const struct option options
[] = {
7111 { "help", no_argument
, NULL
, ARG_HELP
},
7112 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7116 static const struct {
7120 { '0', ACTION_POWEROFF
},
7121 { '6', ACTION_REBOOT
},
7122 { '1', ACTION_RESCUE
},
7123 { '2', ACTION_RUNLEVEL2
},
7124 { '3', ACTION_RUNLEVEL3
},
7125 { '4', ACTION_RUNLEVEL4
},
7126 { '5', ACTION_RUNLEVEL5
},
7127 { 's', ACTION_RESCUE
},
7128 { 'S', ACTION_RESCUE
},
7129 { 'q', ACTION_RELOAD
},
7130 { 'Q', ACTION_RELOAD
},
7131 { 'u', ACTION_REEXEC
},
7132 { 'U', ACTION_REEXEC
}
7141 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7156 assert_not_reached("Unhandled option");
7159 if (optind
>= argc
) {
7160 log_error("%s: required argument missing.", program_invocation_short_name
);
7164 if (optind
+ 1 < argc
) {
7165 log_error("Too many arguments.");
7169 if (strlen(argv
[optind
]) != 1) {
7170 log_error("Expected single character argument.");
7174 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7175 if (table
[i
].from
== argv
[optind
][0])
7178 if (i
>= ELEMENTSOF(table
)) {
7179 log_error("Unknown command '%s'.", argv
[optind
]);
7183 arg_action
= table
[i
].to
;
7190 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7196 static const struct option options
[] = {
7197 { "help", no_argument
, NULL
, ARG_HELP
},
7206 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7217 assert_not_reached("Unhandled option");
7220 if (optind
< argc
) {
7221 log_error("Too many arguments.");
7228 static int parse_argv(int argc
, char *argv
[]) {
7232 if (program_invocation_short_name
) {
7234 if (strstr(program_invocation_short_name
, "halt")) {
7235 arg_action
= ACTION_HALT
;
7236 return halt_parse_argv(argc
, argv
);
7237 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7238 arg_action
= ACTION_POWEROFF
;
7239 return halt_parse_argv(argc
, argv
);
7240 } else if (strstr(program_invocation_short_name
, "reboot")) {
7242 arg_action
= ACTION_KEXEC
;
7244 arg_action
= ACTION_REBOOT
;
7245 return halt_parse_argv(argc
, argv
);
7246 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7247 arg_action
= ACTION_POWEROFF
;
7248 return shutdown_parse_argv(argc
, argv
);
7249 } else if (strstr(program_invocation_short_name
, "init")) {
7251 if (sd_booted() > 0) {
7252 arg_action
= _ACTION_INVALID
;
7253 return telinit_parse_argv(argc
, argv
);
7255 /* Hmm, so some other init system is
7256 * running, we need to forward this
7257 * request to it. For now we simply
7258 * guess that it is Upstart. */
7260 execv(TELINIT
, argv
);
7262 log_error("Couldn't find an alternative telinit implementation to spawn.");
7266 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7267 arg_action
= ACTION_RUNLEVEL
;
7268 return runlevel_parse_argv(argc
, argv
);
7272 arg_action
= ACTION_SYSTEMCTL
;
7273 return systemctl_parse_argv(argc
, argv
);
7276 #ifdef HAVE_SYSV_COMPAT
7277 _pure_
static int action_to_runlevel(void) {
7279 static const char table
[_ACTION_MAX
] = {
7280 [ACTION_HALT
] = '0',
7281 [ACTION_POWEROFF
] = '0',
7282 [ACTION_REBOOT
] = '6',
7283 [ACTION_RUNLEVEL2
] = '2',
7284 [ACTION_RUNLEVEL3
] = '3',
7285 [ACTION_RUNLEVEL4
] = '4',
7286 [ACTION_RUNLEVEL5
] = '5',
7287 [ACTION_RESCUE
] = '1'
7290 assert(arg_action
< _ACTION_MAX
);
7292 return table
[arg_action
];
7296 static int talk_initctl(void) {
7297 #ifdef HAVE_SYSV_COMPAT
7298 struct init_request request
= {
7299 .magic
= INIT_MAGIC
,
7301 .cmd
= INIT_CMD_RUNLVL
7304 _cleanup_close_
int fd
= -1;
7308 rl
= action_to_runlevel();
7312 request
.runlevel
= rl
;
7314 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7316 if (errno
== ENOENT
)
7319 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7322 r
= loop_write(fd
, &request
, sizeof(request
), false);
7324 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7332 static int systemctl_main(int argc
, char *argv
[]) {
7334 static const Verb verbs
[] = {
7335 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7336 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7337 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7338 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7339 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7340 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7341 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7342 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7343 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7344 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7345 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7346 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7347 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7348 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7349 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7350 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7351 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7352 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7353 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7354 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7355 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7356 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7357 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7358 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7359 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7360 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7361 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7362 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7363 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7364 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7365 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7366 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7367 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7368 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7369 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7370 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7371 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7372 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7373 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7374 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7375 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7376 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7377 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7378 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7379 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7380 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7381 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7382 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7383 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7384 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7385 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7386 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7387 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7388 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7389 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7390 { "link", 2, VERB_ANY
, 0, enable_unit
},
7391 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7392 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7393 { "set-default", 2, 2, 0, set_default
},
7394 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7395 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7396 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7397 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7398 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7399 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7403 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7406 static int reload_with_fallback(void) {
7408 /* First, try systemd via D-Bus. */
7409 if (daemon_reload(0, NULL
, NULL
) >= 0)
7412 /* Nothing else worked, so let's try signals */
7413 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7415 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7416 return log_error_errno(errno
, "kill() failed: %m");
7421 static int start_with_fallback(void) {
7423 /* First, try systemd via D-Bus. */
7424 if (start_unit(0, NULL
, NULL
) >= 0)
7427 /* Nothing else worked, so let's try
7429 if (talk_initctl() > 0)
7432 log_error("Failed to talk to init daemon.");
7436 static int halt_now(enum action a
) {
7438 /* The kernel will automaticall flush ATA disks and suchlike
7439 * on reboot(), but the file systems need to be synce'd
7440 * explicitly in advance. */
7443 /* Make sure C-A-D is handled by the kernel from this point
7445 (void) reboot(RB_ENABLE_CAD
);
7450 log_info("Halting.");
7451 (void) reboot(RB_HALT_SYSTEM
);
7454 case ACTION_POWEROFF
:
7455 log_info("Powering off.");
7456 (void) reboot(RB_POWER_OFF
);
7460 case ACTION_REBOOT
: {
7461 _cleanup_free_
char *param
= NULL
;
7463 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7464 log_info("Rebooting with argument '%s'.", param
);
7465 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7468 log_info("Rebooting.");
7469 (void) reboot(RB_AUTOBOOT
);
7474 assert_not_reached("Unknown action.");
7478 static int logind_schedule_shutdown(void) {
7481 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7482 char date
[FORMAT_TIMESTAMP_MAX
];
7487 (void) logind_set_wall_message();
7489 r
= acquire_bus(BUS_FULL
, &bus
);
7493 switch (arg_action
) {
7497 case ACTION_POWEROFF
:
7498 action
= "poweroff";
7513 action
= strjoina("dry-", action
);
7515 r
= sd_bus_call_method(
7517 "org.freedesktop.login1",
7518 "/org/freedesktop/login1",
7519 "org.freedesktop.login1.Manager",
7527 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7529 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7532 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7537 static int halt_main(void) {
7540 r
= logind_check_inhibitors(arg_action
);
7545 return logind_schedule_shutdown();
7547 if (geteuid() != 0) {
7548 if (arg_dry
|| arg_force
> 0) {
7549 log_error("Must be root.");
7553 /* Try logind if we are a normal user and no special
7554 * mode applies. Maybe PolicyKit allows us to shutdown
7556 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7557 r
= logind_reboot(arg_action
);
7560 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7561 /* requested operation is not
7562 * supported on the local system or
7563 * already in progress */
7565 /* on all other errors, try low-level operation */
7569 if (!arg_dry
&& !arg_force
)
7570 return start_with_fallback();
7572 assert(geteuid() == 0);
7575 if (sd_booted() > 0)
7576 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7578 r
= utmp_put_shutdown();
7580 log_warning_errno(r
, "Failed to write utmp record: %m");
7587 r
= halt_now(arg_action
);
7588 return log_error_errno(r
, "Failed to reboot: %m");
7591 static int runlevel_main(void) {
7592 int r
, runlevel
, previous
;
7594 r
= utmp_get_runlevel(&runlevel
, &previous
);
7601 previous
<= 0 ? 'N' : previous
,
7602 runlevel
<= 0 ? 'N' : runlevel
);
7607 static int logind_cancel_shutdown(void) {
7609 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7613 r
= acquire_bus(BUS_FULL
, &bus
);
7617 (void) logind_set_wall_message();
7619 r
= sd_bus_call_method(
7621 "org.freedesktop.login1",
7622 "/org/freedesktop/login1",
7623 "org.freedesktop.login1.Manager",
7624 "CancelScheduledShutdown",
7628 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7632 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7637 int main(int argc
, char*argv
[]) {
7640 setlocale(LC_ALL
, "");
7641 log_parse_environment();
7644 /* Explicitly not on_tty() to avoid setting cached value.
7645 * This becomes relevant for piping output which might be
7647 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7649 r
= parse_argv(argc
, argv
);
7653 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7654 log_info("Running in chroot, ignoring request.");
7659 /* systemctl_main() will print an error message for the bus
7660 * connection, but only if it needs to */
7662 switch (arg_action
) {
7664 case ACTION_SYSTEMCTL
:
7665 r
= systemctl_main(argc
, argv
);
7669 case ACTION_POWEROFF
:
7675 case ACTION_RUNLEVEL2
:
7676 case ACTION_RUNLEVEL3
:
7677 case ACTION_RUNLEVEL4
:
7678 case ACTION_RUNLEVEL5
:
7680 case ACTION_EMERGENCY
:
7681 case ACTION_DEFAULT
:
7682 r
= start_with_fallback();
7687 r
= reload_with_fallback();
7690 case ACTION_CANCEL_SHUTDOWN
:
7691 r
= logind_cancel_shutdown();
7694 case ACTION_RUNLEVEL
:
7695 r
= runlevel_main();
7698 case _ACTION_INVALID
:
7700 assert_not_reached("Unknown action");
7705 ask_password_agent_close();
7706 polkit_agent_close();
7708 strv_free(arg_types
);
7709 strv_free(arg_states
);
7710 strv_free(arg_properties
);
7712 strv_free(arg_wall
);
7717 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7719 return r
< 0 ? EXIT_FAILURE
: r
;