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_value
= false;
107 static bool arg_show_types
= false;
108 static bool arg_ignore_inhibitors
= false;
109 static bool arg_dry
= false;
110 static bool arg_quiet
= false;
111 static bool arg_full
= false;
112 static bool arg_recursive
= false;
113 static int arg_force
= 0;
114 static bool arg_ask_password
= false;
115 static bool arg_runtime
= false;
116 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
117 static char **arg_wall
= NULL
;
118 static const char *arg_kill_who
= NULL
;
119 static int arg_signal
= SIGTERM
;
120 static char *arg_root
= NULL
;
121 static usec_t arg_when
= 0;
143 ACTION_CANCEL_SHUTDOWN
,
145 } arg_action
= ACTION_SYSTEMCTL
;
146 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
147 static const char *arg_host
= NULL
;
148 static unsigned arg_lines
= 10;
149 static OutputMode arg_output
= OUTPUT_SHORT
;
150 static bool arg_plain
= false;
151 static bool arg_firmware_setup
= false;
152 static bool arg_now
= false;
154 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
155 static int halt_now(enum action a
);
156 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
158 static bool original_stdout_is_tty
;
160 typedef enum BusFocus
{
161 BUS_FULL
, /* The full bus indicated via --system or --user */
162 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
166 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
168 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
171 assert(focus
< _BUS_FOCUS_MAX
);
174 /* We only go directly to the manager, if we are using a local transport */
175 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
178 if (!busses
[focus
]) {
181 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
183 if (focus
== BUS_MANAGER
)
184 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
186 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
188 return log_error_errno(r
, "Failed to connect to bus: %m");
190 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
193 *ret
= busses
[focus
];
197 static void release_busses(void) {
200 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
201 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
204 static void ask_password_agent_open_if_enabled(void) {
206 /* Open the password agent as a child process if necessary */
208 if (!arg_ask_password
)
211 if (arg_scope
!= UNIT_FILE_SYSTEM
)
214 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
217 ask_password_agent_open();
220 static void polkit_agent_open_if_enabled(void) {
222 /* Open the polkit agent as a child process if necessary */
224 if (!arg_ask_password
)
227 if (arg_scope
!= UNIT_FILE_SYSTEM
)
230 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
236 static OutputFlags
get_output_flags(void) {
238 arg_all
* OUTPUT_SHOW_ALL
|
239 arg_full
* OUTPUT_FULL_WIDTH
|
240 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
241 colors_enabled() * OUTPUT_COLOR
|
242 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
245 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
248 if (!sd_bus_error_is_set(error
))
251 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
252 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
253 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
254 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
255 return EXIT_NOPERMISSION
;
257 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
258 return EXIT_NOTINSTALLED
;
260 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
261 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
262 return EXIT_NOTIMPLEMENTED
;
264 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
265 return EXIT_NOTCONFIGURED
;
273 static bool install_client_side(void) {
275 /* Decides when to execute enable/disable/... operations
276 * client-side rather than server-side. */
278 if (running_in_chroot() > 0)
281 if (sd_booted() <= 0)
284 if (!isempty(arg_root
))
287 if (arg_scope
== UNIT_FILE_GLOBAL
)
290 /* Unsupported environment variable, mostly for debugging purposes */
291 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
297 static int compare_unit_info(const void *a
, const void *b
) {
298 const UnitInfo
*u
= a
, *v
= b
;
302 /* First, order by machine */
303 if (!u
->machine
&& v
->machine
)
305 if (u
->machine
&& !v
->machine
)
307 if (u
->machine
&& v
->machine
) {
308 r
= strcasecmp(u
->machine
, v
->machine
);
313 /* Second, order by unit type */
314 d1
= strrchr(u
->id
, '.');
315 d2
= strrchr(v
->id
, '.');
317 r
= strcasecmp(d1
, d2
);
322 /* Third, order by name */
323 return strcasecmp(u
->id
, v
->id
);
326 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
327 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
333 dot
= strrchr(u
->id
, '.');
337 if (!strv_find(arg_types
, dot
+1))
344 if (!strv_isempty(arg_states
))
347 /* By default show all units except the ones in inactive
348 * state and with no pending job */
352 if (streq(u
->active_state
, "inactive") || u
->following
[0])
358 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
359 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
361 unsigned n_shown
= 0;
364 max_id_len
= strlen("UNIT");
365 load_len
= strlen("LOAD");
366 active_len
= strlen("ACTIVE");
367 sub_len
= strlen("SUB");
368 job_len
= strlen("JOB");
371 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
372 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
373 load_len
= MAX(load_len
, strlen(u
->load_state
));
374 active_len
= MAX(active_len
, strlen(u
->active_state
));
375 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
377 if (u
->job_id
!= 0) {
378 job_len
= MAX(job_len
, strlen(u
->job_type
));
382 if (!arg_no_legend
&&
383 (streq(u
->active_state
, "failed") ||
384 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
388 if (!arg_full
&& original_stdout_is_tty
) {
391 id_len
= MIN(max_id_len
, 25u);
392 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
395 basic_len
+= job_len
+ 1;
397 if (basic_len
< (unsigned) columns()) {
398 unsigned extra_len
, incr
;
399 extra_len
= columns() - basic_len
;
401 /* Either UNIT already got 25, or is fully satisfied.
402 * Grant up to 25 to DESC now. */
403 incr
= MIN(extra_len
, 25u);
407 /* split the remaining space between UNIT and DESC,
408 * but do not give UNIT more than it needs. */
410 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
412 desc_len
+= extra_len
- incr
;
418 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
419 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
420 const char *on_loaded
= "", *off_loaded
= "";
421 const char *on_active
= "", *off_active
= "";
422 const char *on_circle
= "", *off_circle
= "";
426 if (!n_shown
&& !arg_no_legend
) {
431 printf("%-*s %-*s %-*s %-*s ",
434 active_len
, "ACTIVE",
438 printf("%-*s ", job_len
, "JOB");
440 if (!arg_full
&& arg_no_pager
)
441 printf("%.*s\n", desc_len
, "DESCRIPTION");
443 printf("%s\n", "DESCRIPTION");
448 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
449 on_loaded
= ansi_highlight_red();
450 on_circle
= ansi_highlight_yellow();
451 off_loaded
= off_circle
= ansi_normal();
453 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
454 on_circle
= on_active
= ansi_highlight_red();
455 off_circle
= off_active
= ansi_normal();
460 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
469 e
= ellipsize(id
, id_len
, 33);
477 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
479 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
480 on_active
, id_len
, id
, off_active
,
481 on_loaded
, load_len
, u
->load_state
, off_loaded
,
482 on_active
, active_len
, u
->active_state
,
483 sub_len
, u
->sub_state
, off_active
,
484 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
487 printf("%.*s\n", desc_len
, u
->description
);
489 printf("%s\n", u
->description
);
492 if (!arg_no_legend
) {
493 const char *on
, *off
;
497 "LOAD = Reflects whether the unit definition was properly loaded.\n"
498 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
499 "SUB = The low-level unit activation state, values depend on unit type.");
500 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
501 on
= ansi_highlight();
504 on
= ansi_highlight_red();
509 printf("%s%u loaded units listed.%s\n"
510 "To show all installed unit files use 'systemctl list-unit-files'.\n",
513 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
514 "To show all installed unit files use 'systemctl list-unit-files'.\n",
521 static int get_unit_list(
525 UnitInfo
**unit_infos
,
527 sd_bus_message
**_reply
) {
529 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
530 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
531 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
540 r
= sd_bus_message_new_method_call(
543 "org.freedesktop.systemd1",
544 "/org/freedesktop/systemd1",
545 "org.freedesktop.systemd1.Manager",
546 "ListUnitsFiltered");
549 return bus_log_create_error(r
);
551 r
= sd_bus_message_append_strv(m
, arg_states
);
553 return bus_log_create_error(r
);
555 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
557 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
559 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
561 return bus_log_parse_error(r
);
563 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
566 if (!output_show_unit(&u
, patterns
))
569 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
572 (*unit_infos
)[c
++] = u
;
575 return bus_log_parse_error(r
);
577 r
= sd_bus_message_exit_container(reply
);
579 return bus_log_parse_error(r
);
587 static void message_set_freep(Set
**set
) {
590 while ((m
= set_steal_first(*set
)))
591 sd_bus_message_unref(m
);
596 static int get_unit_list_recursive(
599 UnitInfo
**_unit_infos
,
603 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
604 _cleanup_(message_set_freep
) Set
*replies
;
605 sd_bus_message
*reply
;
613 replies
= set_new(NULL
);
617 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
621 r
= set_put(replies
, reply
);
623 sd_bus_message_unref(reply
);
628 _cleanup_strv_free_
char **machines
= NULL
;
631 r
= sd_get_machine_names(&machines
);
633 return log_error_errno(r
, "Failed to get machine names: %m");
635 STRV_FOREACH(i
, machines
) {
636 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
639 r
= sd_bus_open_system_machine(&container
, *i
);
641 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
645 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
651 r
= set_put(replies
, reply
);
653 sd_bus_message_unref(reply
);
658 *_machines
= machines
;
663 *_unit_infos
= unit_infos
;
672 static int list_units(int argc
, char *argv
[], void *userdata
) {
673 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
674 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
675 _cleanup_strv_free_
char **machines
= NULL
;
679 pager_open(arg_no_pager
, false);
681 r
= acquire_bus(BUS_MANAGER
, &bus
);
685 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
689 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
690 return output_units_list(unit_infos
, r
);
693 static int get_triggered_units(
698 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
705 r
= sd_bus_get_property_strv(
707 "org.freedesktop.systemd1",
709 "org.freedesktop.systemd1.Unit",
714 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
719 static int get_listening(
721 const char* unit_path
,
724 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
725 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
726 const char *type
, *path
;
729 r
= sd_bus_get_property(
731 "org.freedesktop.systemd1",
733 "org.freedesktop.systemd1.Socket",
739 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
741 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
743 return bus_log_parse_error(r
);
745 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
747 r
= strv_extend(listening
, type
);
751 r
= strv_extend(listening
, path
);
758 return bus_log_parse_error(r
);
760 r
= sd_bus_message_exit_container(reply
);
762 return bus_log_parse_error(r
);
774 /* Note: triggered is a list here, although it almost certainly
775 * will always be one unit. Nevertheless, dbus API allows for multiple
776 * values, so let's follow that. */
779 /* The strv above is shared. free is set only in the first one. */
783 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
789 if (!a
->machine
&& b
->machine
)
791 if (a
->machine
&& !b
->machine
)
793 if (a
->machine
&& b
->machine
) {
794 o
= strcasecmp(a
->machine
, b
->machine
);
799 o
= strcmp(a
->path
, b
->path
);
801 o
= strcmp(a
->type
, b
->type
);
806 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
807 struct socket_info
*s
;
808 unsigned pathlen
= strlen("LISTEN"),
809 typelen
= strlen("TYPE") * arg_show_types
,
810 socklen
= strlen("UNIT"),
811 servlen
= strlen("ACTIVATES");
812 const char *on
, *off
;
814 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
818 socklen
= MAX(socklen
, strlen(s
->id
));
820 typelen
= MAX(typelen
, strlen(s
->type
));
821 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
823 STRV_FOREACH(a
, s
->triggered
)
824 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
825 servlen
= MAX(servlen
, tmp
);
830 printf("%-*s %-*.*s%-*s %s\n",
832 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
836 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
837 _cleanup_free_
char *j
= NULL
;
842 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
850 printf("%-*s %-*s %-*s",
851 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
854 pathlen
, path
, socklen
, s
->id
);
855 STRV_FOREACH(a
, s
->triggered
)
857 a
== s
->triggered
? "" : ",", *a
);
861 on
= ansi_highlight();
866 on
= ansi_highlight_red();
870 if (!arg_no_legend
) {
871 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
873 printf("Pass --all to see loaded but inactive sockets, too.\n");
879 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
880 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
881 _cleanup_strv_free_
char **machines
= NULL
;
882 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
883 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
885 struct socket_info
*s
;
891 pager_open(arg_no_pager
, false);
893 r
= acquire_bus(BUS_MANAGER
, &bus
);
897 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
901 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
902 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
905 if (!endswith(u
->id
, ".socket"))
908 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
912 c
= get_listening(bus
, u
->unit_path
, &listening
);
918 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
923 for (i
= 0; i
< c
; i
++)
924 socket_infos
[cs
+ i
] = (struct socket_info
) {
925 .machine
= u
->machine
,
927 .type
= listening
[i
*2],
928 .path
= listening
[i
*2 + 1],
929 .triggered
= triggered
,
930 .own_triggered
= i
==0,
933 /* from this point on we will cleanup those socket_infos */
936 listening
= triggered
= NULL
; /* avoid cleanup */
939 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
940 (__compar_fn_t
) socket_info_compare
);
942 output_sockets_list(socket_infos
, cs
);
945 assert(cs
== 0 || socket_infos
);
946 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
949 if (s
->own_triggered
)
950 strv_free(s
->triggered
);
956 static int get_next_elapse(
959 dual_timestamp
*next
) {
961 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
969 r
= sd_bus_get_property_trivial(
971 "org.freedesktop.systemd1",
973 "org.freedesktop.systemd1.Timer",
974 "NextElapseUSecMonotonic",
979 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
981 r
= sd_bus_get_property_trivial(
983 "org.freedesktop.systemd1",
985 "org.freedesktop.systemd1.Timer",
986 "NextElapseUSecRealtime",
991 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
997 static int get_last_trigger(
1002 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1009 r
= sd_bus_get_property_trivial(
1011 "org.freedesktop.systemd1",
1013 "org.freedesktop.systemd1.Timer",
1019 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1025 const char* machine
;
1028 usec_t last_trigger
;
1032 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1038 if (!a
->machine
&& b
->machine
)
1040 if (a
->machine
&& !b
->machine
)
1042 if (a
->machine
&& b
->machine
) {
1043 o
= strcasecmp(a
->machine
, b
->machine
);
1048 if (a
->next_elapse
< b
->next_elapse
)
1050 if (a
->next_elapse
> b
->next_elapse
)
1053 return strcmp(a
->id
, b
->id
);
1056 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1057 struct timer_info
*t
;
1059 nextlen
= strlen("NEXT"),
1060 leftlen
= strlen("LEFT"),
1061 lastlen
= strlen("LAST"),
1062 passedlen
= strlen("PASSED"),
1063 unitlen
= strlen("UNIT"),
1064 activatelen
= strlen("ACTIVATES");
1066 const char *on
, *off
;
1068 assert(timer_infos
|| n
== 0);
1070 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1074 if (t
->next_elapse
> 0) {
1075 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1077 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1078 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1080 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1081 leftlen
= MAX(leftlen
, strlen(trel
));
1084 if (t
->last_trigger
> 0) {
1085 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1087 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1088 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1090 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1091 passedlen
= MAX(passedlen
, strlen(trel
));
1094 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1096 STRV_FOREACH(a
, t
->triggered
)
1097 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1099 activatelen
= MAX(activatelen
, ul
);
1104 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1108 passedlen
, "PASSED",
1112 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1113 _cleanup_free_
char *j
= NULL
;
1115 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1116 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1119 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1120 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1122 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1123 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1126 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1133 printf("%-*s %-*s %-*s %-*s %-*s",
1134 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1136 STRV_FOREACH(a
, t
->triggered
)
1138 a
== t
->triggered
? "" : ",", *a
);
1142 on
= ansi_highlight();
1143 off
= ansi_normal();
1147 on
= ansi_highlight_red();
1148 off
= ansi_normal();
1151 if (!arg_no_legend
) {
1152 printf("%s%u timers listed.%s\n", on
, n
, off
);
1154 printf("Pass --all to see loaded but inactive timers, too.\n");
1160 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1166 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1169 if (next
->monotonic
> nw
->monotonic
)
1170 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1172 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1174 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1175 next_elapse
= MIN(converted
, next
->realtime
);
1177 next_elapse
= converted
;
1180 next_elapse
= next
->realtime
;
1185 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1186 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1187 _cleanup_strv_free_
char **machines
= NULL
;
1188 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1189 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1190 struct timer_info
*t
;
1198 pager_open(arg_no_pager
, false);
1200 r
= acquire_bus(BUS_MANAGER
, &bus
);
1204 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1208 dual_timestamp_get(&nw
);
1210 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1211 _cleanup_strv_free_
char **triggered
= NULL
;
1212 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1215 if (!endswith(u
->id
, ".timer"))
1218 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1222 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1226 get_last_trigger(bus
, u
->unit_path
, &last
);
1228 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1233 m
= calc_next_elapse(&nw
, &next
);
1235 timer_infos
[c
++] = (struct timer_info
) {
1236 .machine
= u
->machine
,
1239 .last_trigger
= last
,
1240 .triggered
= triggered
,
1243 triggered
= NULL
; /* avoid cleanup */
1246 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1247 (__compar_fn_t
) timer_info_compare
);
1249 output_timers_list(timer_infos
, c
);
1252 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1253 strv_free(t
->triggered
);
1258 static int compare_unit_file_list(const void *a
, const void *b
) {
1259 const char *d1
, *d2
;
1260 const UnitFileList
*u
= a
, *v
= b
;
1262 d1
= strrchr(u
->path
, '.');
1263 d2
= strrchr(v
->path
, '.');
1268 r
= strcasecmp(d1
, d2
);
1273 return strcasecmp(basename(u
->path
), basename(v
->path
));
1276 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1277 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1280 if (!strv_isempty(arg_types
)) {
1283 dot
= strrchr(u
->path
, '.');
1287 if (!strv_find(arg_types
, dot
+1))
1291 if (!strv_isempty(arg_states
) &&
1292 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1298 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1299 unsigned max_id_len
, id_cols
, state_cols
;
1300 const UnitFileList
*u
;
1302 max_id_len
= strlen("UNIT FILE");
1303 state_cols
= strlen("STATE");
1305 for (u
= units
; u
< units
+ c
; u
++) {
1306 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1307 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1311 unsigned basic_cols
;
1313 id_cols
= MIN(max_id_len
, 25u);
1314 basic_cols
= 1 + id_cols
+ state_cols
;
1315 if (basic_cols
< (unsigned) columns())
1316 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1318 id_cols
= max_id_len
;
1321 printf("%-*s %-*s\n",
1322 id_cols
, "UNIT FILE",
1323 state_cols
, "STATE");
1325 for (u
= units
; u
< units
+ c
; u
++) {
1326 _cleanup_free_
char *e
= NULL
;
1327 const char *on
, *off
;
1330 if (IN_SET(u
->state
,
1332 UNIT_FILE_MASKED_RUNTIME
,
1335 on
= ansi_highlight_red();
1336 off
= ansi_normal();
1337 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1338 on
= ansi_highlight_green();
1339 off
= ansi_normal();
1343 id
= basename(u
->path
);
1345 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1347 printf("%-*s %s%-*s%s\n",
1348 id_cols
, e
? e
: id
,
1349 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1353 printf("\n%u unit files listed.\n", c
);
1356 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1357 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1358 _cleanup_free_ UnitFileList
*units
= NULL
;
1366 pager_open(arg_no_pager
, false);
1368 if (install_client_side()) {
1374 h
= hashmap_new(&string_hash_ops
);
1378 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1380 unit_file_list_free(h
);
1381 return log_error_errno(r
, "Failed to get unit file list: %m");
1384 n_units
= hashmap_size(h
);
1386 units
= new(UnitFileList
, n_units
);
1387 if (!units
&& n_units
> 0) {
1388 unit_file_list_free(h
);
1392 HASHMAP_FOREACH(u
, h
, i
) {
1393 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1400 assert(c
<= n_units
);
1403 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1406 r
= acquire_bus(BUS_MANAGER
, &bus
);
1410 r
= sd_bus_call_method(
1412 "org.freedesktop.systemd1",
1413 "/org/freedesktop/systemd1",
1414 "org.freedesktop.systemd1.Manager",
1420 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1422 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1424 return bus_log_parse_error(r
);
1426 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1428 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1431 units
[c
] = (struct UnitFileList
) {
1433 unit_file_state_from_string(state
)
1436 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1441 return bus_log_parse_error(r
);
1443 r
= sd_bus_message_exit_container(reply
);
1445 return bus_log_parse_error(r
);
1448 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1449 output_unit_file_list(units
, c
);
1451 if (install_client_side()) {
1452 for (unit
= units
; unit
< units
+ c
; unit
++)
1459 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1460 _cleanup_free_
char *n
= NULL
;
1461 size_t max_len
= MAX(columns(),20u);
1467 for (i
= level
- 1; i
>= 0; i
--) {
1469 if (len
> max_len
- 3 && !arg_full
) {
1470 printf("%s...\n",max_len
% 2 ? "" : " ");
1473 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1477 if (len
> max_len
- 3 && !arg_full
) {
1478 printf("%s...\n",max_len
% 2 ? "" : " ");
1482 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1486 printf("%s\n", name
);
1490 n
= ellipsize(name
, max_len
-len
, 100);
1498 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1500 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1501 [DEPENDENCY_FORWARD
] = "Requires\0"
1506 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1511 [DEPENDENCY_AFTER
] = "After\0",
1512 [DEPENDENCY_BEFORE
] = "Before\0",
1515 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1516 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1517 _cleanup_strv_free_
char **ret
= NULL
;
1518 _cleanup_free_
char *path
= NULL
;
1524 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1526 path
= unit_dbus_path_from_name(name
);
1530 r
= sd_bus_call_method(
1532 "org.freedesktop.systemd1",
1534 "org.freedesktop.DBus.Properties",
1538 "s", "org.freedesktop.systemd1.Unit");
1540 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1542 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1544 return bus_log_parse_error(r
);
1546 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1549 r
= sd_bus_message_read(reply
, "s", &prop
);
1551 return bus_log_parse_error(r
);
1553 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1554 r
= sd_bus_message_skip(reply
, "v");
1556 return bus_log_parse_error(r
);
1559 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1561 return bus_log_parse_error(r
);
1563 r
= bus_message_read_strv_extend(reply
, &ret
);
1565 return bus_log_parse_error(r
);
1567 r
= sd_bus_message_exit_container(reply
);
1569 return bus_log_parse_error(r
);
1572 r
= sd_bus_message_exit_container(reply
);
1574 return bus_log_parse_error(r
);
1578 return bus_log_parse_error(r
);
1580 r
= sd_bus_message_exit_container(reply
);
1582 return bus_log_parse_error(r
);
1590 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1591 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1593 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1595 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1598 return strcasecmp(*a
, *b
);
1601 static int list_dependencies_one(
1606 unsigned int branches
) {
1608 _cleanup_strv_free_
char **deps
= NULL
;
1616 r
= strv_extend(units
, name
);
1620 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1624 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1626 STRV_FOREACH(c
, deps
) {
1627 if (strv_contains(*units
, *c
)) {
1629 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1639 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1642 (void) get_state_one_unit(bus
, *c
, &active_state
);
1643 switch (active_state
) {
1645 case UNIT_RELOADING
:
1646 case UNIT_ACTIVATING
:
1647 on
= ansi_highlight_green();
1651 case UNIT_DEACTIVATING
:
1656 on
= ansi_highlight_red();
1660 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1663 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1667 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1668 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1675 strv_remove(*units
, name
);
1680 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1681 _cleanup_strv_free_
char **units
= NULL
;
1682 _cleanup_free_
char *unit
= NULL
;
1688 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1690 return log_error_errno(r
, "Failed to mangle unit name: %m");
1694 u
= SPECIAL_DEFAULT_TARGET
;
1696 pager_open(arg_no_pager
, false);
1698 r
= acquire_bus(BUS_MANAGER
, &bus
);
1704 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1707 struct machine_info
{
1711 char *control_group
;
1712 uint32_t n_failed_units
;
1717 static const struct bus_properties_map machine_info_property_map
[] = {
1718 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1719 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1720 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1721 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1722 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1726 static void machine_info_clear(struct machine_info
*info
) {
1730 free(info
->control_group
);
1735 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1741 for (i
= 0; i
< n
; i
++)
1742 machine_info_clear(&machine_infos
[i
]);
1744 free(machine_infos
);
1747 static int compare_machine_info(const void *a
, const void *b
) {
1748 const struct machine_info
*u
= a
, *v
= b
;
1750 if (u
->is_host
!= v
->is_host
)
1751 return u
->is_host
> v
->is_host
? -1 : 1;
1753 return strcasecmp(u
->name
, v
->name
);
1756 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1757 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1763 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1770 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1777 static bool output_show_machine(const char *name
, char **patterns
) {
1778 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1781 static int get_machine_list(
1783 struct machine_info
**_machine_infos
,
1786 struct machine_info
*machine_infos
= NULL
;
1787 _cleanup_strv_free_
char **m
= NULL
;
1788 _cleanup_free_
char *hn
= NULL
;
1793 hn
= gethostname_malloc();
1797 if (output_show_machine(hn
, patterns
)) {
1798 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1801 machine_infos
[c
].is_host
= true;
1802 machine_infos
[c
].name
= hn
;
1805 get_machine_properties(bus
, &machine_infos
[c
]);
1809 r
= sd_get_machine_names(&m
);
1811 return log_error_errno(r
, "Failed to get machine list: %m");
1813 STRV_FOREACH(i
, m
) {
1814 _cleanup_free_
char *class = NULL
;
1816 if (!output_show_machine(*i
, patterns
))
1819 sd_machine_get_class(*i
, &class);
1820 if (!streq_ptr(class, "container"))
1823 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1824 free_machines_list(machine_infos
, c
);
1828 machine_infos
[c
].is_host
= false;
1829 machine_infos
[c
].name
= strdup(*i
);
1830 if (!machine_infos
[c
].name
) {
1831 free_machines_list(machine_infos
, c
);
1835 get_machine_properties(NULL
, &machine_infos
[c
]);
1839 *_machine_infos
= machine_infos
;
1843 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1844 struct machine_info
*m
;
1847 namelen
= sizeof("NAME") - 1,
1848 statelen
= sizeof("STATE") - 1,
1849 failedlen
= sizeof("FAILED") - 1,
1850 jobslen
= sizeof("JOBS") - 1;
1852 assert(machine_infos
|| n
== 0);
1854 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1855 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1856 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1857 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1858 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1860 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1864 if (!arg_no_legend
) {
1868 printf("%-*s %-*s %-*s %-*s\n",
1871 failedlen
, "FAILED",
1875 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1876 const char *on_state
= "", *off_state
= "";
1877 const char *on_failed
= "", *off_failed
= "";
1878 bool circle
= false;
1880 if (streq_ptr(m
->state
, "degraded")) {
1881 on_state
= ansi_highlight_red();
1882 off_state
= ansi_normal();
1884 } else if (!streq_ptr(m
->state
, "running")) {
1885 on_state
= ansi_highlight_yellow();
1886 off_state
= ansi_normal();
1890 if (m
->n_failed_units
> 0) {
1891 on_failed
= ansi_highlight_red();
1892 off_failed
= ansi_normal();
1894 on_failed
= off_failed
= "";
1897 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1900 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1901 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1902 on_state
, statelen
, strna(m
->state
), off_state
,
1903 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1904 jobslen
, m
->n_jobs
);
1906 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1907 namelen
, strna(m
->name
),
1908 on_state
, statelen
, strna(m
->state
), off_state
,
1909 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1910 jobslen
, m
->n_jobs
);
1914 printf("\n%u machines listed.\n", n
);
1917 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1918 struct machine_info
*machine_infos
= NULL
;
1922 if (geteuid() != 0) {
1923 log_error("Must be root.");
1927 pager_open(arg_no_pager
, false);
1929 r
= acquire_bus(BUS_MANAGER
, &bus
);
1933 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1937 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1938 output_machines_list(machine_infos
, r
);
1939 free_machines_list(machine_infos
, r
);
1944 static int get_default(int argc
, char *argv
[], void *userdata
) {
1945 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1946 _cleanup_free_
char *_path
= NULL
;
1950 if (install_client_side()) {
1951 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1953 return log_error_errno(r
, "Failed to get default target: %m");
1957 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1960 r
= acquire_bus(BUS_MANAGER
, &bus
);
1964 r
= sd_bus_call_method(
1966 "org.freedesktop.systemd1",
1967 "/org/freedesktop/systemd1",
1968 "org.freedesktop.systemd1.Manager",
1974 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1976 r
= sd_bus_message_read(reply
, "s", &path
);
1978 return bus_log_parse_error(r
);
1982 printf("%s\n", path
);
1987 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1990 assert(changes
|| n_changes
== 0);
1992 for (i
= 0; i
< n_changes
; i
++) {
1993 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1994 log_info("Created symlink %s, pointing to %s.", changes
[i
].path
, changes
[i
].source
);
1996 log_info("Removed symlink %s.", changes
[i
].path
);
2000 static int set_default(int argc
, char *argv
[], void *userdata
) {
2001 _cleanup_free_
char *unit
= NULL
;
2007 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2009 return log_error_errno(r
, "Failed to mangle unit name: %m");
2011 if (install_client_side()) {
2012 UnitFileChange
*changes
= NULL
;
2013 unsigned n_changes
= 0;
2015 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2017 return log_error_errno(r
, "Failed to set default target: %m");
2020 dump_unit_file_changes(changes
, n_changes
);
2022 unit_file_changes_free(changes
, n_changes
);
2025 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2026 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2029 polkit_agent_open_if_enabled();
2031 r
= acquire_bus(BUS_MANAGER
, &bus
);
2035 r
= sd_bus_call_method(
2037 "org.freedesktop.systemd1",
2038 "/org/freedesktop/systemd1",
2039 "org.freedesktop.systemd1.Manager",
2045 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2047 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2051 /* Try to reload if enabled */
2053 r
= daemon_reload(argc
, argv
, userdata
);
2063 const char *name
, *type
, *state
;
2066 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2067 unsigned id_len
, unit_len
, type_len
, state_len
;
2068 const struct job_info
*j
;
2069 const char *on
, *off
;
2070 bool shorten
= false;
2072 assert(n
== 0 || jobs
);
2075 if (!arg_no_legend
) {
2076 on
= ansi_highlight_green();
2077 off
= ansi_normal();
2079 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2084 pager_open(arg_no_pager
, false);
2086 id_len
= strlen("JOB");
2087 unit_len
= strlen("UNIT");
2088 type_len
= strlen("TYPE");
2089 state_len
= strlen("STATE");
2091 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2092 uint32_t id
= j
->id
;
2093 assert(j
->name
&& j
->type
&& j
->state
);
2095 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2096 unit_len
= MAX(unit_len
, strlen(j
->name
));
2097 type_len
= MAX(type_len
, strlen(j
->type
));
2098 state_len
= MAX(state_len
, strlen(j
->state
));
2101 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2102 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2107 printf("%*s %-*s %-*s %-*s\n",
2111 state_len
, "STATE");
2113 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2114 _cleanup_free_
char *e
= NULL
;
2116 if (streq(j
->state
, "running")) {
2117 on
= ansi_highlight();
2118 off
= ansi_normal();
2122 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2123 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2125 on
, unit_len
, e
? e
: j
->name
, off
,
2127 on
, state_len
, j
->state
, off
);
2130 if (!arg_no_legend
) {
2131 on
= ansi_highlight();
2132 off
= ansi_normal();
2134 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2138 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2139 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2142 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2143 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2144 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2145 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2146 _cleanup_free_
struct job_info
*jobs
= NULL
;
2152 bool skipped
= false;
2154 pager_open(arg_no_pager
, false);
2156 r
= acquire_bus(BUS_MANAGER
, &bus
);
2160 r
= sd_bus_call_method(
2162 "org.freedesktop.systemd1",
2163 "/org/freedesktop/systemd1",
2164 "org.freedesktop.systemd1.Manager",
2170 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2172 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2174 return bus_log_parse_error(r
);
2176 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2177 struct job_info job
= { id
, name
, type
, state
};
2179 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2184 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2190 return bus_log_parse_error(r
);
2192 r
= sd_bus_message_exit_container(reply
);
2194 return bus_log_parse_error(r
);
2196 output_jobs_list(jobs
, c
, skipped
);
2200 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2206 return daemon_reload(argc
, argv
, userdata
);
2208 polkit_agent_open_if_enabled();
2210 r
= acquire_bus(BUS_MANAGER
, &bus
);
2214 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2215 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2219 q
= safe_atou32(*name
, &id
);
2221 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2223 q
= sd_bus_call_method(
2225 "org.freedesktop.systemd1",
2226 "/org/freedesktop/systemd1",
2227 "org.freedesktop.systemd1.Manager",
2233 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2242 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2243 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2247 /* We ignore all errors here, since this is used to show a
2250 /* We don't use unit_dbus_path_from_name() directly since we
2251 * don't want to load the unit if it isn't loaded. */
2253 r
= sd_bus_call_method(
2255 "org.freedesktop.systemd1",
2256 "/org/freedesktop/systemd1",
2257 "org.freedesktop.systemd1.Manager",
2265 r
= sd_bus_message_read(reply
, "o", &path
);
2269 r
= sd_bus_get_property_trivial(
2271 "org.freedesktop.systemd1",
2273 "org.freedesktop.systemd1.Unit",
2283 static void warn_unit_file_changed(const char *name
) {
2284 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2285 ansi_highlight_red(),
2288 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2291 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2298 STRV_FOREACH(p
, lp
->unit_path
) {
2299 _cleanup_free_
char *path
;
2301 path
= path_join(arg_root
, *p
, unit_name
);
2305 if (access(path
, F_OK
) == 0) {
2315 static int unit_find_paths(
2317 const char *unit_name
,
2319 char **fragment_path
,
2320 char ***dropin_paths
) {
2322 _cleanup_free_
char *path
= NULL
;
2323 _cleanup_strv_free_
char **dropins
= NULL
;
2327 * Finds where the unit is defined on disk. Returns 0 if the unit
2328 * is not found. Returns 1 if it is found, and sets
2329 * - the path to the unit in *path, if it exists on disk,
2330 * - and a strv of existing drop-ins in *dropins,
2331 * if the arg is not NULL and any dropins were found.
2335 assert(fragment_path
);
2338 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2339 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2340 _cleanup_free_
char *unit
= NULL
;
2342 unit
= unit_dbus_path_from_name(unit_name
);
2346 r
= sd_bus_get_property_string(
2348 "org.freedesktop.systemd1",
2350 "org.freedesktop.systemd1.Unit",
2355 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2358 r
= sd_bus_get_property_strv(
2360 "org.freedesktop.systemd1",
2362 "org.freedesktop.systemd1.Unit",
2367 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2370 _cleanup_set_free_ Set
*names
;
2372 names
= set_new(NULL
);
2376 r
= set_put(names
, unit_name
);
2378 return log_error_errno(r
, "Failed to add unit name: %m");
2380 r
= unit_file_find_path(lp
, unit_name
, &path
);
2385 _cleanup_free_
char *template = NULL
;
2387 r
= unit_name_template(unit_name
, &template);
2388 if (r
< 0 && r
!= -EINVAL
)
2389 return log_error_errno(r
, "Failed to determine template name: %m");
2391 r
= unit_file_find_path(lp
, template, &path
);
2398 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2406 if (!isempty(path
)) {
2407 *fragment_path
= path
;
2412 if (dropin_paths
&& !strv_isempty(dropins
)) {
2413 *dropin_paths
= dropins
;
2419 log_error("No files found for %s.", unit_name
);
2424 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2425 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2426 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2427 _cleanup_free_
char *buf
= NULL
;
2428 UnitActiveState state
;
2433 assert(active_state
);
2435 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2437 r
= sd_bus_call_method(
2439 "org.freedesktop.systemd1",
2440 "/org/freedesktop/systemd1",
2441 "org.freedesktop.systemd1.Manager",
2447 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2448 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2450 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2451 * considered inactive. */
2452 state
= UNIT_INACTIVE
;
2455 r
= sd_bus_message_read(reply
, "o", &path
);
2457 return bus_log_parse_error(r
);
2459 r
= sd_bus_get_property_string(
2461 "org.freedesktop.systemd1",
2463 "org.freedesktop.systemd1.Unit",
2468 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2470 state
= unit_active_state_from_string(buf
);
2471 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2472 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2477 *active_state
= state
;
2481 static int check_triggering_units(
2485 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2486 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2487 _cleanup_strv_free_
char **triggered_by
= NULL
;
2488 bool print_warning_label
= true;
2489 UnitActiveState active_state
;
2493 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2495 return log_error_errno(r
, "Failed to mangle unit name: %m");
2497 path
= unit_dbus_path_from_name(n
);
2501 r
= sd_bus_get_property_string(
2503 "org.freedesktop.systemd1",
2505 "org.freedesktop.systemd1.Unit",
2510 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2512 if (streq(load_state
, "masked"))
2515 r
= sd_bus_get_property_strv(
2517 "org.freedesktop.systemd1",
2519 "org.freedesktop.systemd1.Unit",
2524 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2526 STRV_FOREACH(i
, triggered_by
) {
2527 r
= get_state_one_unit(bus
, *i
, &active_state
);
2531 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2534 if (print_warning_label
) {
2535 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2536 print_warning_label
= false;
2539 log_warning(" %s", *i
);
2545 static const struct {
2548 } unit_actions
[] = {
2549 { "start", "StartUnit" },
2550 { "stop", "StopUnit" },
2551 { "condstop", "StopUnit" },
2552 { "reload", "ReloadUnit" },
2553 { "restart", "RestartUnit" },
2554 { "try-restart", "TryRestartUnit" },
2555 { "condrestart", "TryRestartUnit" },
2556 { "reload-or-restart", "ReloadOrRestartUnit" },
2557 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2558 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2559 { "condreload", "ReloadOrTryRestartUnit" },
2560 { "force-reload", "ReloadOrTryRestartUnit" }
2563 static const char *verb_to_method(const char *verb
) {
2566 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2567 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2568 return unit_actions
[i
].method
;
2573 static const char *method_to_verb(const char *method
) {
2576 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2577 if (streq_ptr(unit_actions
[i
].method
, method
))
2578 return unit_actions
[i
].verb
;
2583 static int start_unit_one(
2588 sd_bus_error
*error
,
2589 BusWaitForJobs
*w
) {
2591 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2600 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2602 r
= sd_bus_call_method(
2604 "org.freedesktop.systemd1",
2605 "/org/freedesktop/systemd1",
2606 "org.freedesktop.systemd1.Manager",
2614 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2615 /* There's always a fallback possible for
2616 * legacy actions. */
2617 return -EADDRNOTAVAIL
;
2619 verb
= method_to_verb(method
);
2621 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2623 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2624 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2625 log_error("See %s logs and 'systemctl%s status %s' for details.",
2626 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2627 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2633 r
= sd_bus_message_read(reply
, "o", &path
);
2635 return bus_log_parse_error(r
);
2637 if (need_daemon_reload(bus
, name
) > 0)
2638 warn_unit_file_changed(name
);
2641 log_debug("Adding %s to the set", path
);
2642 r
= bus_wait_for_jobs_add(w
, path
);
2650 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2651 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2658 STRV_FOREACH(name
, names
) {
2662 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2664 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2666 return log_error_errno(r
, "Failed to mangle name: %m");
2668 if (string_is_glob(t
))
2669 r
= strv_consume(&globs
, t
);
2671 r
= strv_consume(&mangled
, t
);
2676 /* Query the manager only if any of the names are a glob, since
2677 * this is fairly expensive */
2678 if (!strv_isempty(globs
)) {
2679 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2680 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2681 size_t allocated
, n
;
2683 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2687 n
= strv_length(mangled
);
2690 for (i
= 0; i
< r
; i
++) {
2691 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2694 mangled
[n
] = strdup(unit_infos
[i
].id
);
2698 mangled
[++n
] = NULL
;
2703 mangled
= NULL
; /* do not free */
2708 static const struct {
2712 } action_table
[_ACTION_MAX
] = {
2713 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2714 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2715 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2716 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2717 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2718 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2719 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2720 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2721 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2722 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2723 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2724 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2725 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2726 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2727 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2730 static enum action
verb_to_action(const char *verb
) {
2733 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2734 if (streq_ptr(action_table
[i
].verb
, verb
))
2737 return _ACTION_INVALID
;
2740 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2741 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2742 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2743 _cleanup_strv_free_
char **names
= NULL
;
2748 ask_password_agent_open_if_enabled();
2749 polkit_agent_open_if_enabled();
2751 r
= acquire_bus(BUS_MANAGER
, &bus
);
2755 if (arg_action
== ACTION_SYSTEMCTL
) {
2758 method
= verb_to_method(argv
[0]);
2759 action
= verb_to_action(argv
[0]);
2761 if (streq(argv
[0], "isolate")) {
2765 mode
= action_table
[action
].mode
?: arg_job_mode
;
2767 one_name
= action_table
[action
].target
;
2769 assert(arg_action
< ELEMENTSOF(action_table
));
2770 assert(action_table
[arg_action
].target
);
2772 method
= "StartUnit";
2774 mode
= action_table
[arg_action
].mode
;
2775 one_name
= action_table
[arg_action
].target
;
2779 names
= strv_new(one_name
, NULL
);
2781 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2783 return log_error_errno(r
, "Failed to expand names: %m");
2786 if (!arg_no_block
) {
2787 r
= bus_wait_for_jobs_new(bus
, &w
);
2789 return log_error_errno(r
, "Could not watch jobs: %m");
2792 STRV_FOREACH(name
, names
) {
2793 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2796 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2797 if (r
>= 0 && q
< 0)
2798 r
= translate_bus_error_to_exit_status(q
, &error
);
2801 if (!arg_no_block
) {
2802 int q
, arg_count
= 0;
2803 const char* extra_args
[4] = {};
2805 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2806 extra_args
[arg_count
++] = "--user";
2808 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2809 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2810 extra_args
[arg_count
++] = "-H";
2811 extra_args
[arg_count
++] = arg_host
;
2812 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2813 extra_args
[arg_count
++] = "-M";
2814 extra_args
[arg_count
++] = arg_host
;
2817 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2821 /* When stopping units, warn if they can still be triggered by
2822 * another active unit (socket, path, timer) */
2823 if (!arg_quiet
&& streq(method
, "StopUnit"))
2824 STRV_FOREACH(name
, names
)
2825 check_triggering_units(bus
, *name
);
2831 static int logind_set_wall_message(void) {
2833 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2835 _cleanup_free_
char *m
= NULL
;
2838 r
= acquire_bus(BUS_FULL
, &bus
);
2842 m
= strv_join(arg_wall
, " ");
2846 r
= sd_bus_call_method(
2848 "org.freedesktop.login1",
2849 "/org/freedesktop/login1",
2850 "org.freedesktop.login1.Manager",
2859 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2865 /* Ask systemd-logind, which might grant access to unprivileged users
2866 * through PolicyKit */
2867 static int logind_reboot(enum action a
) {
2869 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2870 const char *method
, *description
;
2874 polkit_agent_open_if_enabled();
2875 (void) logind_set_wall_message();
2877 r
= acquire_bus(BUS_FULL
, &bus
);
2885 description
= "reboot system";
2888 case ACTION_POWEROFF
:
2889 method
= "PowerOff";
2890 description
= "power off system";
2893 case ACTION_SUSPEND
:
2895 description
= "suspend system";
2898 case ACTION_HIBERNATE
:
2899 method
= "Hibernate";
2900 description
= "hibernate system";
2903 case ACTION_HYBRID_SLEEP
:
2904 method
= "HybridSleep";
2905 description
= "put system into hybrid sleep";
2912 r
= sd_bus_call_method(
2914 "org.freedesktop.login1",
2915 "/org/freedesktop/login1",
2916 "org.freedesktop.login1.Manager",
2920 "b", arg_ask_password
);
2922 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2930 static int logind_check_inhibitors(enum action a
) {
2932 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2933 _cleanup_strv_free_
char **sessions
= NULL
;
2934 const char *what
, *who
, *why
, *mode
;
2941 if (arg_ignore_inhibitors
|| arg_force
> 0)
2953 r
= acquire_bus(BUS_FULL
, &bus
);
2957 r
= sd_bus_call_method(
2959 "org.freedesktop.login1",
2960 "/org/freedesktop/login1",
2961 "org.freedesktop.login1.Manager",
2967 /* If logind is not around, then there are no inhibitors... */
2970 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2972 return bus_log_parse_error(r
);
2974 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2975 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2976 _cleanup_strv_free_
char **sv
= NULL
;
2978 if (!streq(mode
, "block"))
2981 sv
= strv_split(what
, ":");
2985 if ((pid_t
) pid
< 0)
2986 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2988 if (!strv_contains(sv
,
2993 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2996 get_process_comm(pid
, &comm
);
2997 user
= uid_to_name(uid
);
2999 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3000 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3005 return bus_log_parse_error(r
);
3007 r
= sd_bus_message_exit_container(reply
);
3009 return bus_log_parse_error(r
);
3011 /* Check for current sessions */
3012 sd_get_sessions(&sessions
);
3013 STRV_FOREACH(s
, sessions
) {
3014 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3016 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3019 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3022 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3025 sd_session_get_tty(*s
, &tty
);
3026 sd_session_get_seat(*s
, &seat
);
3027 sd_session_get_service(*s
, &service
);
3028 user
= uid_to_name(uid
);
3030 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3037 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3038 action_table
[a
].verb
);
3046 static int logind_prepare_firmware_setup(void) {
3048 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3052 r
= acquire_bus(BUS_FULL
, &bus
);
3056 r
= sd_bus_call_method(
3058 "org.freedesktop.login1",
3059 "/org/freedesktop/login1",
3060 "org.freedesktop.login1.Manager",
3061 "SetRebootToFirmwareSetup",
3066 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3070 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3075 static int prepare_firmware_setup(void) {
3078 if (!arg_firmware_setup
)
3081 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3083 r
= efi_set_reboot_to_firmware(true);
3085 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3090 return logind_prepare_firmware_setup();
3093 static int set_exit_code(uint8_t code
) {
3094 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3098 r
= acquire_bus(BUS_MANAGER
, &bus
);
3102 r
= sd_bus_call_method(
3104 "org.freedesktop.systemd1",
3105 "/org/freedesktop/systemd1",
3106 "org.freedesktop.systemd1.Manager",
3112 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3117 static int start_special(int argc
, char *argv
[], void *userdata
) {
3123 a
= verb_to_action(argv
[0]);
3125 r
= logind_check_inhibitors(a
);
3129 if (arg_force
>= 2 && geteuid() != 0) {
3130 log_error("Must be root.");
3134 r
= prepare_firmware_setup();
3138 if (a
== ACTION_REBOOT
&& argc
> 1) {
3139 r
= update_reboot_param_file(argv
[1]);
3143 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3146 /* If the exit code is not given on the command line,
3147 * don't reset it to zero: just keep it as it might
3148 * have been set previously. */
3150 r
= safe_atou8(argv
[1], &code
);
3152 return log_error_errno(r
, "Invalid exit code.");
3154 r
= set_exit_code(code
);
3159 if (arg_force
>= 2 &&
3166 if (arg_force
>= 1 &&
3173 return daemon_reload(argc
, argv
, userdata
);
3175 /* First try logind, to allow authentication with polkit */
3181 ACTION_HYBRID_SLEEP
)) {
3182 r
= logind_reboot(a
);
3185 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3186 /* requested operation is not supported or already in progress */
3189 /* On all other errors, try low-level operation */
3192 return start_unit(argc
, argv
, userdata
);
3195 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3196 _cleanup_strv_free_
char **names
= NULL
;
3197 UnitActiveState active_state
;
3203 r
= acquire_bus(BUS_MANAGER
, &bus
);
3207 r
= expand_names(bus
, args
, NULL
, &names
);
3209 return log_error_errno(r
, "Failed to expand names: %m");
3211 STRV_FOREACH(name
, names
) {
3212 r
= get_state_one_unit(bus
, *name
, &active_state
);
3217 puts(unit_active_state_to_string(active_state
));
3219 for (i
= 0; i
< nb_states
; ++i
)
3220 if (good_states
[i
] == active_state
)
3224 /* use the given return code for the case that we won't find
3225 * any unit which matches the list */
3226 return found
? 0 : code
;
3229 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3230 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3231 /* According to LSB: 3, "program is not running" */
3232 return check_unit_generic(3, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3235 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3236 const UnitActiveState states
[] = { UNIT_FAILED
};
3237 return check_unit_generic(1, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3240 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3241 _cleanup_strv_free_
char **names
= NULL
;
3242 char *kill_who
= NULL
, **name
;
3246 polkit_agent_open_if_enabled();
3248 r
= acquire_bus(BUS_MANAGER
, &bus
);
3253 arg_kill_who
= "all";
3255 /* --fail was specified */
3256 if (streq(arg_job_mode
, "fail"))
3257 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3259 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3261 return log_error_errno(r
, "Failed to expand names: %m");
3263 STRV_FOREACH(name
, names
) {
3264 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3266 q
= sd_bus_call_method(
3268 "org.freedesktop.systemd1",
3269 "/org/freedesktop/systemd1",
3270 "org.freedesktop.systemd1.Manager",
3274 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3276 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3285 typedef struct ExecStatusInfo
{
3293 usec_t start_timestamp
;
3294 usec_t exit_timestamp
;
3299 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3302 static void exec_status_info_free(ExecStatusInfo
*i
) {
3311 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3312 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3315 int32_t code
, status
;
3321 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3323 return bus_log_parse_error(r
);
3327 r
= sd_bus_message_read(m
, "s", &path
);
3329 return bus_log_parse_error(r
);
3331 i
->path
= strdup(path
);
3335 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3337 return bus_log_parse_error(r
);
3339 r
= sd_bus_message_read(m
,
3342 &start_timestamp
, &start_timestamp_monotonic
,
3343 &exit_timestamp
, &exit_timestamp_monotonic
,
3347 return bus_log_parse_error(r
);
3350 i
->start_timestamp
= (usec_t
) start_timestamp
;
3351 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3352 i
->pid
= (pid_t
) pid
;
3356 r
= sd_bus_message_exit_container(m
);
3358 return bus_log_parse_error(r
);
3363 typedef struct UnitStatusInfo
{
3365 const char *load_state
;
3366 const char *active_state
;
3367 const char *sub_state
;
3368 const char *unit_file_state
;
3369 const char *unit_file_preset
;
3371 const char *description
;
3372 const char *following
;
3374 char **documentation
;
3376 const char *fragment_path
;
3377 const char *source_path
;
3378 const char *control_group
;
3380 char **dropin_paths
;
3382 const char *load_error
;
3385 usec_t inactive_exit_timestamp
;
3386 usec_t inactive_exit_timestamp_monotonic
;
3387 usec_t active_enter_timestamp
;
3388 usec_t active_exit_timestamp
;
3389 usec_t inactive_enter_timestamp
;
3391 bool need_daemon_reload
;
3397 const char *status_text
;
3398 const char *pid_file
;
3402 usec_t start_timestamp
;
3403 usec_t exit_timestamp
;
3405 int exit_code
, exit_status
;
3407 usec_t condition_timestamp
;
3408 bool condition_result
;
3409 bool failed_condition_trigger
;
3410 bool failed_condition_negate
;
3411 const char *failed_condition
;
3412 const char *failed_condition_parameter
;
3414 usec_t assert_timestamp
;
3416 bool failed_assert_trigger
;
3417 bool failed_assert_negate
;
3418 const char *failed_assert
;
3419 const char *failed_assert_parameter
;
3422 unsigned n_accepted
;
3423 unsigned n_connections
;
3426 /* Pairs of type, path */
3430 const char *sysfs_path
;
3432 /* Mount, Automount */
3439 uint64_t memory_current
;
3440 uint64_t memory_limit
;
3441 uint64_t cpu_usage_nsec
;
3442 uint64_t tasks_current
;
3445 LIST_HEAD(ExecStatusInfo
, exec
);
3448 static void print_status_info(
3453 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3455 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3456 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3462 /* This shows pretty information about a unit. See
3463 * print_property() for a low-level property printer */
3465 if (streq_ptr(i
->active_state
, "failed")) {
3466 active_on
= ansi_highlight_red();
3467 active_off
= ansi_normal();
3468 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3469 active_on
= ansi_highlight_green();
3470 active_off
= ansi_normal();
3472 active_on
= active_off
= "";
3474 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3476 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3477 printf(" - %s", i
->description
);
3482 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3484 if (streq_ptr(i
->load_state
, "error")) {
3485 on
= ansi_highlight_red();
3486 off
= ansi_normal();
3490 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3492 if (i
->load_error
!= 0)
3493 printf(" Loaded: %s%s%s (Reason: %s)\n",
3494 on
, strna(i
->load_state
), off
, i
->load_error
);
3495 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3496 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3497 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3498 else if (path
&& !isempty(i
->unit_file_state
))
3499 printf(" Loaded: %s%s%s (%s; %s)\n",
3500 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3502 printf(" Loaded: %s%s%s (%s)\n",
3503 on
, strna(i
->load_state
), off
, path
);
3505 printf(" Loaded: %s%s%s\n",
3506 on
, strna(i
->load_state
), off
);
3509 printf("Transient: yes\n");
3511 if (!strv_isempty(i
->dropin_paths
)) {
3512 _cleanup_free_
char *dir
= NULL
;
3516 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3517 if (! dir
|| last
) {
3518 printf(dir
? " " : " Drop-In: ");
3522 dir
= dirname_malloc(*dropin
);
3528 printf("%s\n %s", dir
,
3529 draw_special_char(DRAW_TREE_RIGHT
));
3532 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3534 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3538 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3540 printf(" Active: %s%s (%s)%s",
3541 active_on
, strna(i
->active_state
), ss
, active_off
);
3543 printf(" Active: %s%s%s",
3544 active_on
, strna(i
->active_state
), active_off
);
3546 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3547 printf(" (Result: %s)", i
->result
);
3549 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3550 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3551 (streq_ptr(i
->active_state
, "inactive") ||
3552 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3553 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3554 i
->active_exit_timestamp
;
3556 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3557 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3560 printf(" since %s; %s\n", s2
, s1
);
3562 printf(" since %s\n", s2
);
3566 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3567 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3568 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3570 printf("Condition: start %scondition failed%s at %s%s%s\n",
3571 ansi_highlight_yellow(), ansi_normal(),
3572 s2
, s1
? "; " : "", strempty(s1
));
3573 if (i
->failed_condition_trigger
)
3574 printf(" none of the trigger conditions were met\n");
3575 else if (i
->failed_condition
)
3576 printf(" %s=%s%s was not met\n",
3577 i
->failed_condition
,
3578 i
->failed_condition_negate
? "!" : "",
3579 i
->failed_condition_parameter
);
3582 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3583 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3584 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3586 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3587 ansi_highlight_red(), ansi_normal(),
3588 s2
, s1
? "; " : "", strempty(s1
));
3589 if (i
->failed_assert_trigger
)
3590 printf(" none of the trigger assertions were met\n");
3591 else if (i
->failed_assert
)
3592 printf(" %s=%s%s was not met\n",
3594 i
->failed_assert_negate
? "!" : "",
3595 i
->failed_assert_parameter
);
3599 printf(" Device: %s\n", i
->sysfs_path
);
3601 printf(" Where: %s\n", i
->where
);
3603 printf(" What: %s\n", i
->what
);
3605 STRV_FOREACH(t
, i
->documentation
)
3606 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3608 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3609 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3612 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3614 LIST_FOREACH(exec
, p
, i
->exec
) {
3615 _cleanup_free_
char *argv
= NULL
;
3618 /* Only show exited processes here */
3622 argv
= strv_join(p
->argv
, " ");
3623 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3625 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3627 on
= ansi_highlight_red();
3628 off
= ansi_normal();
3632 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3634 if (p
->code
== CLD_EXITED
) {
3637 printf("status=%i", p
->status
);
3639 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3644 printf("signal=%s", signal_to_string(p
->status
));
3646 printf(")%s\n", off
);
3648 if (i
->main_pid
== p
->pid
&&
3649 i
->start_timestamp
== p
->start_timestamp
&&
3650 i
->exit_timestamp
== p
->start_timestamp
)
3651 /* Let's not show this twice */
3654 if (p
->pid
== i
->control_pid
)
3658 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3659 if (i
->main_pid
> 0) {
3660 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3663 _cleanup_free_
char *comm
= NULL
;
3664 get_process_comm(i
->main_pid
, &comm
);
3666 printf(" (%s)", comm
);
3667 } else if (i
->exit_code
> 0) {
3668 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3670 if (i
->exit_code
== CLD_EXITED
) {
3673 printf("status=%i", i
->exit_status
);
3675 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3680 printf("signal=%s", signal_to_string(i
->exit_status
));
3684 if (i
->control_pid
> 0)
3688 if (i
->control_pid
> 0) {
3689 _cleanup_free_
char *c
= NULL
;
3691 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3693 get_process_comm(i
->control_pid
, &c
);
3702 printf(" Status: \"%s\"\n", i
->status_text
);
3703 if (i
->status_errno
> 0)
3704 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3706 if (i
->tasks_current
!= (uint64_t) -1) {
3707 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3709 if (i
->tasks_max
!= (uint64_t) -1)
3710 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3715 if (i
->memory_current
!= (uint64_t) -1) {
3716 char buf
[FORMAT_BYTES_MAX
];
3718 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3720 if (i
->memory_limit
!= (uint64_t) -1)
3721 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3726 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3727 char buf
[FORMAT_TIMESPAN_MAX
];
3728 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3731 if (i
->control_group
&&
3732 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3733 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3736 printf(" CGroup: %s\n", i
->control_group
);
3738 if (IN_SET(arg_transport
,
3739 BUS_TRANSPORT_LOCAL
,
3740 BUS_TRANSPORT_MACHINE
)) {
3743 static const char prefix
[] = " ";
3746 if (c
> sizeof(prefix
) - 1)
3747 c
-= sizeof(prefix
) - 1;
3751 if (i
->main_pid
> 0)
3752 extra
[k
++] = i
->main_pid
;
3754 if (i
->control_pid
> 0)
3755 extra
[k
++] = i
->control_pid
;
3757 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3761 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3762 show_journal_by_unit(
3767 i
->inactive_exit_timestamp_monotonic
,
3770 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3771 SD_JOURNAL_LOCAL_ONLY
,
3772 arg_scope
== UNIT_FILE_SYSTEM
,
3775 if (i
->need_daemon_reload
)
3776 warn_unit_file_changed(i
->id
);
3779 static void show_unit_help(UnitStatusInfo
*i
) {
3784 if (!i
->documentation
) {
3785 log_info("Documentation for %s not known.", i
->id
);
3789 STRV_FOREACH(p
, i
->documentation
)
3790 if (startswith(*p
, "man:"))
3791 show_man_page(*p
+ 4, false);
3793 log_info("Can't show: %s", *p
);
3796 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3803 switch (contents
[0]) {
3805 case SD_BUS_TYPE_STRING
: {
3808 r
= sd_bus_message_read(m
, "s", &s
);
3810 return bus_log_parse_error(r
);
3813 if (streq(name
, "Id"))
3815 else if (streq(name
, "LoadState"))
3817 else if (streq(name
, "ActiveState"))
3818 i
->active_state
= s
;
3819 else if (streq(name
, "SubState"))
3821 else if (streq(name
, "Description"))
3823 else if (streq(name
, "FragmentPath"))
3824 i
->fragment_path
= s
;
3825 else if (streq(name
, "SourcePath"))
3828 else if (streq(name
, "DefaultControlGroup")) {
3830 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3832 i
->control_group
= e
;
3835 else if (streq(name
, "ControlGroup"))
3836 i
->control_group
= s
;
3837 else if (streq(name
, "StatusText"))
3839 else if (streq(name
, "PIDFile"))
3841 else if (streq(name
, "SysFSPath"))
3843 else if (streq(name
, "Where"))
3845 else if (streq(name
, "What"))
3847 else if (streq(name
, "Following"))
3849 else if (streq(name
, "UnitFileState"))
3850 i
->unit_file_state
= s
;
3851 else if (streq(name
, "UnitFilePreset"))
3852 i
->unit_file_preset
= s
;
3853 else if (streq(name
, "Result"))
3860 case SD_BUS_TYPE_BOOLEAN
: {
3863 r
= sd_bus_message_read(m
, "b", &b
);
3865 return bus_log_parse_error(r
);
3867 if (streq(name
, "Accept"))
3869 else if (streq(name
, "NeedDaemonReload"))
3870 i
->need_daemon_reload
= b
;
3871 else if (streq(name
, "ConditionResult"))
3872 i
->condition_result
= b
;
3873 else if (streq(name
, "AssertResult"))
3874 i
->assert_result
= b
;
3875 else if (streq(name
, "Transient"))
3881 case SD_BUS_TYPE_UINT32
: {
3884 r
= sd_bus_message_read(m
, "u", &u
);
3886 return bus_log_parse_error(r
);
3888 if (streq(name
, "MainPID")) {
3890 i
->main_pid
= (pid_t
) u
;
3893 } else if (streq(name
, "ControlPID"))
3894 i
->control_pid
= (pid_t
) u
;
3895 else if (streq(name
, "ExecMainPID")) {
3897 i
->main_pid
= (pid_t
) u
;
3898 } else if (streq(name
, "NAccepted"))
3900 else if (streq(name
, "NConnections"))
3901 i
->n_connections
= u
;
3906 case SD_BUS_TYPE_INT32
: {
3909 r
= sd_bus_message_read(m
, "i", &j
);
3911 return bus_log_parse_error(r
);
3913 if (streq(name
, "ExecMainCode"))
3914 i
->exit_code
= (int) j
;
3915 else if (streq(name
, "ExecMainStatus"))
3916 i
->exit_status
= (int) j
;
3917 else if (streq(name
, "StatusErrno"))
3918 i
->status_errno
= (int) j
;
3923 case SD_BUS_TYPE_UINT64
: {
3926 r
= sd_bus_message_read(m
, "t", &u
);
3928 return bus_log_parse_error(r
);
3930 if (streq(name
, "ExecMainStartTimestamp"))
3931 i
->start_timestamp
= (usec_t
) u
;
3932 else if (streq(name
, "ExecMainExitTimestamp"))
3933 i
->exit_timestamp
= (usec_t
) u
;
3934 else if (streq(name
, "ActiveEnterTimestamp"))
3935 i
->active_enter_timestamp
= (usec_t
) u
;
3936 else if (streq(name
, "InactiveEnterTimestamp"))
3937 i
->inactive_enter_timestamp
= (usec_t
) u
;
3938 else if (streq(name
, "InactiveExitTimestamp"))
3939 i
->inactive_exit_timestamp
= (usec_t
) u
;
3940 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3941 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3942 else if (streq(name
, "ActiveExitTimestamp"))
3943 i
->active_exit_timestamp
= (usec_t
) u
;
3944 else if (streq(name
, "ConditionTimestamp"))
3945 i
->condition_timestamp
= (usec_t
) u
;
3946 else if (streq(name
, "AssertTimestamp"))
3947 i
->assert_timestamp
= (usec_t
) u
;
3948 else if (streq(name
, "MemoryCurrent"))
3949 i
->memory_current
= u
;
3950 else if (streq(name
, "MemoryLimit"))
3951 i
->memory_limit
= u
;
3952 else if (streq(name
, "TasksCurrent"))
3953 i
->tasks_current
= u
;
3954 else if (streq(name
, "TasksMax"))
3956 else if (streq(name
, "CPUUsageNSec"))
3957 i
->cpu_usage_nsec
= u
;
3962 case SD_BUS_TYPE_ARRAY
:
3964 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3965 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3967 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3969 return bus_log_parse_error(r
);
3971 info
= new0(ExecStatusInfo
, 1);
3975 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3977 info
->name
= strdup(name
);
3981 LIST_PREPEND(exec
, i
->exec
, info
);
3983 info
= new0(ExecStatusInfo
, 1);
3989 return bus_log_parse_error(r
);
3991 r
= sd_bus_message_exit_container(m
);
3993 return bus_log_parse_error(r
);
3997 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3998 const char *type
, *path
;
4000 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4002 return bus_log_parse_error(r
);
4004 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4006 r
= strv_extend(&i
->listen
, type
);
4010 r
= strv_extend(&i
->listen
, path
);
4015 return bus_log_parse_error(r
);
4017 r
= sd_bus_message_exit_container(m
);
4019 return bus_log_parse_error(r
);
4023 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4025 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4027 return bus_log_parse_error(r
);
4029 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4031 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4033 return bus_log_parse_error(r
);
4035 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4036 const char *cond
, *param
;
4037 int trigger
, negate
;
4040 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4042 return bus_log_parse_error(r
);
4044 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4045 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4046 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4047 i
->failed_condition
= cond
;
4048 i
->failed_condition_trigger
= trigger
;
4049 i
->failed_condition_negate
= negate
;
4050 i
->failed_condition_parameter
= param
;
4054 return bus_log_parse_error(r
);
4056 r
= sd_bus_message_exit_container(m
);
4058 return bus_log_parse_error(r
);
4060 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4061 const char *cond
, *param
;
4062 int trigger
, negate
;
4065 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4067 return bus_log_parse_error(r
);
4069 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4070 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4071 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4072 i
->failed_assert
= cond
;
4073 i
->failed_assert_trigger
= trigger
;
4074 i
->failed_assert_negate
= negate
;
4075 i
->failed_assert_parameter
= param
;
4079 return bus_log_parse_error(r
);
4081 r
= sd_bus_message_exit_container(m
);
4083 return bus_log_parse_error(r
);
4090 case SD_BUS_TYPE_STRUCT_BEGIN
:
4092 if (streq(name
, "LoadError")) {
4093 const char *n
, *message
;
4095 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4097 return bus_log_parse_error(r
);
4099 if (!isempty(message
))
4100 i
->load_error
= message
;
4113 r
= sd_bus_message_skip(m
, contents
);
4115 return bus_log_parse_error(r
);
4120 #define print_prop(name, fmt, ...) \
4123 printf(fmt "\n", __VA_ARGS__); \
4125 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4128 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4134 /* This is a low-level property printer, see
4135 * print_status_info() for the nicer output */
4137 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4138 /* skip what we didn't read */
4139 r
= sd_bus_message_skip(m
, contents
);
4143 switch (contents
[0]) {
4145 case SD_BUS_TYPE_STRUCT_BEGIN
:
4147 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4150 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4152 return bus_log_parse_error(r
);
4155 print_prop(name
, "%"PRIu32
, u
);
4157 print_prop(name
, "%s", "");
4161 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4164 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4166 return bus_log_parse_error(r
);
4168 if (arg_all
|| !isempty(s
))
4169 print_prop(name
, "%s", s
);
4173 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4174 const char *a
= NULL
, *b
= NULL
;
4176 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4178 return bus_log_parse_error(r
);
4180 if (arg_all
|| !isempty(a
) || !isempty(b
))
4181 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4184 } else if (streq_ptr(name
, "SystemCallFilter")) {
4185 _cleanup_strv_free_
char **l
= NULL
;
4188 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4190 return bus_log_parse_error(r
);
4192 r
= sd_bus_message_read(m
, "b", &whitelist
);
4194 return bus_log_parse_error(r
);
4196 r
= sd_bus_message_read_strv(m
, &l
);
4198 return bus_log_parse_error(r
);
4200 r
= sd_bus_message_exit_container(m
);
4202 return bus_log_parse_error(r
);
4204 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4209 fputs(name
, stdout
);
4216 STRV_FOREACH(i
, l
) {
4224 fputc('\n', stdout
);
4232 case SD_BUS_TYPE_ARRAY
:
4234 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4238 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4240 return bus_log_parse_error(r
);
4242 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4243 print_prop("EnvironmentFile", "%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4246 return bus_log_parse_error(r
);
4248 r
= sd_bus_message_exit_container(m
);
4250 return bus_log_parse_error(r
);
4254 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4255 const char *type
, *path
;
4257 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4259 return bus_log_parse_error(r
);
4261 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4262 print_prop(type
, "%s", path
);
4264 return bus_log_parse_error(r
);
4266 r
= sd_bus_message_exit_container(m
);
4268 return bus_log_parse_error(r
);
4272 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4273 const char *type
, *path
;
4275 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4277 return bus_log_parse_error(r
);
4279 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4283 printf("Listen%s=%s\n", type
, path
);
4285 return bus_log_parse_error(r
);
4287 r
= sd_bus_message_exit_container(m
);
4289 return bus_log_parse_error(r
);
4293 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4295 uint64_t value
, next_elapse
;
4297 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4299 return bus_log_parse_error(r
);
4301 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4302 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4304 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4305 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4306 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4309 return bus_log_parse_error(r
);
4311 r
= sd_bus_message_exit_container(m
);
4313 return bus_log_parse_error(r
);
4317 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4318 ExecStatusInfo info
= {};
4320 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4322 return bus_log_parse_error(r
);
4324 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4325 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4326 _cleanup_free_
char *tt
;
4328 tt
= strv_join(info
.argv
, " ");
4331 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4334 yes_no(info
.ignore
),
4335 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4336 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4338 sigchld_code_to_string(info
.code
),
4340 info
.code
== CLD_EXITED
? "" : "/",
4341 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4344 strv_free(info
.argv
);
4348 r
= sd_bus_message_exit_container(m
);
4350 return bus_log_parse_error(r
);
4354 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4355 const char *path
, *rwm
;
4357 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4359 return bus_log_parse_error(r
);
4361 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4362 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4364 return bus_log_parse_error(r
);
4366 r
= sd_bus_message_exit_container(m
);
4368 return bus_log_parse_error(r
);
4372 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4376 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4378 return bus_log_parse_error(r
);
4380 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4381 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4383 return bus_log_parse_error(r
);
4385 r
= sd_bus_message_exit_container(m
);
4387 return bus_log_parse_error(r
);
4391 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4395 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4397 return bus_log_parse_error(r
);
4399 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4400 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4402 return bus_log_parse_error(r
);
4404 r
= sd_bus_message_exit_container(m
);
4406 return bus_log_parse_error(r
);
4414 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4416 return bus_log_parse_error(r
);
4419 r
= sd_bus_message_skip(m
, contents
);
4421 return bus_log_parse_error(r
);
4424 printf("%s=[unprintable]\n", name
);
4430 static int show_one(
4434 bool show_properties
,
4438 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4439 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4440 UnitStatusInfo info
= {
4441 .memory_current
= (uint64_t) -1,
4442 .memory_limit
= (uint64_t) -1,
4443 .cpu_usage_nsec
= (uint64_t) -1,
4444 .tasks_current
= (uint64_t) -1,
4445 .tasks_max
= (uint64_t) -1,
4453 log_debug("Showing one %s", path
);
4455 r
= sd_bus_call_method(
4457 "org.freedesktop.systemd1",
4459 "org.freedesktop.DBus.Properties",
4465 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4467 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4469 return bus_log_parse_error(r
);
4476 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4477 const char *name
, *contents
;
4479 r
= sd_bus_message_read(reply
, "s", &name
);
4481 return bus_log_parse_error(r
);
4483 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4485 return bus_log_parse_error(r
);
4487 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4489 return bus_log_parse_error(r
);
4491 if (show_properties
)
4492 r
= print_property(name
, reply
, contents
);
4494 r
= status_property(name
, reply
, &info
, contents
);
4498 r
= sd_bus_message_exit_container(reply
);
4500 return bus_log_parse_error(r
);
4502 r
= sd_bus_message_exit_container(reply
);
4504 return bus_log_parse_error(r
);
4507 return bus_log_parse_error(r
);
4509 r
= sd_bus_message_exit_container(reply
);
4511 return bus_log_parse_error(r
);
4515 if (!show_properties
) {
4516 if (streq(verb
, "help"))
4517 show_unit_help(&info
);
4519 print_status_info(&info
, ellipsized
);
4522 strv_free(info
.documentation
);
4523 strv_free(info
.dropin_paths
);
4524 strv_free(info
.listen
);
4526 if (!streq_ptr(info
.active_state
, "active") &&
4527 !streq_ptr(info
.active_state
, "reloading") &&
4528 streq(verb
, "status")) {
4529 /* According to LSB: "program not running" */
4530 /* 0: program is running or service is OK
4531 * 1: program is dead and /run PID file exists
4532 * 2: program is dead and /run/lock lock file exists
4533 * 3: program is not running
4534 * 4: program or service status is unknown
4536 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4542 while ((p
= info
.exec
)) {
4543 LIST_REMOVE(exec
, info
.exec
, p
);
4544 exec_status_info_free(p
);
4550 static int get_unit_dbus_path_by_pid(
4555 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4556 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4560 r
= sd_bus_call_method(
4562 "org.freedesktop.systemd1",
4563 "/org/freedesktop/systemd1",
4564 "org.freedesktop.systemd1.Manager",
4570 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4572 r
= sd_bus_message_read(reply
, "o", &u
);
4574 return bus_log_parse_error(r
);
4584 static int show_all(
4587 bool show_properties
,
4591 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4592 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4597 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4601 pager_open(arg_no_pager
, false);
4605 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4607 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4608 _cleanup_free_
char *p
= NULL
;
4610 p
= unit_dbus_path_from_name(u
->id
);
4614 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4617 else if (r
> 0 && ret
== 0)
4624 static int show_system_status(sd_bus
*bus
) {
4625 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4626 _cleanup_free_
char *hn
= NULL
;
4627 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4628 const char *on
, *off
;
4631 hn
= gethostname_malloc();
4635 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4637 return log_error_errno(r
, "Failed to read server status: %m");
4639 if (streq_ptr(mi
.state
, "degraded")) {
4640 on
= ansi_highlight_red();
4641 off
= ansi_normal();
4642 } else if (!streq_ptr(mi
.state
, "running")) {
4643 on
= ansi_highlight_yellow();
4644 off
= ansi_normal();
4648 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4650 printf(" State: %s%s%s\n",
4651 on
, strna(mi
.state
), off
);
4653 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
4654 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
4656 printf(" Since: %s; %s\n",
4657 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4658 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4660 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4661 if (IN_SET(arg_transport
,
4662 BUS_TRANSPORT_LOCAL
,
4663 BUS_TRANSPORT_MACHINE
)) {
4664 static const char prefix
[] = " ";
4668 if (c
> sizeof(prefix
) - 1)
4669 c
-= sizeof(prefix
) - 1;
4673 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4679 static int show(int argc
, char *argv
[], void *userdata
) {
4680 bool show_properties
, show_status
, show_help
, new_line
= false;
4681 bool ellipsized
= false;
4687 show_properties
= streq(argv
[0], "show");
4688 show_status
= streq(argv
[0], "status");
4689 show_help
= streq(argv
[0], "help");
4691 if (show_help
&& argc
<= 1) {
4692 log_error("This command expects one or more unit names. Did you mean --help?");
4696 pager_open(arg_no_pager
, false);
4699 /* Increase max number of open files to 16K if we can, we
4700 * might needs this when browsing journal files, which might
4701 * be split up into many files. */
4702 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4704 r
= acquire_bus(BUS_MANAGER
, &bus
);
4708 /* If no argument is specified inspect the manager itself */
4709 if (show_properties
&& argc
<= 1)
4710 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4712 if (show_status
&& argc
<= 1) {
4714 pager_open(arg_no_pager
, false);
4715 show_system_status(bus
);
4719 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4721 _cleanup_free_
char **patterns
= NULL
;
4724 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4725 _cleanup_free_
char *unit
= NULL
;
4728 if (safe_atou32(*name
, &id
) < 0) {
4729 if (strv_push(&patterns
, *name
) < 0)
4733 } else if (show_properties
) {
4734 /* Interpret as job id */
4735 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4739 /* Interpret as PID */
4740 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4747 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4750 else if (r
> 0 && ret
== 0)
4754 if (!strv_isempty(patterns
)) {
4755 _cleanup_strv_free_
char **names
= NULL
;
4757 r
= expand_names(bus
, patterns
, NULL
, &names
);
4759 return log_error_errno(r
, "Failed to expand names: %m");
4761 STRV_FOREACH(name
, names
) {
4762 _cleanup_free_
char *unit
;
4764 unit
= unit_dbus_path_from_name(*name
);
4768 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4771 else if (r
> 0 && ret
== 0)
4777 if (ellipsized
&& !arg_quiet
)
4778 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4783 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4787 assert(user_runtime
);
4790 if (arg_scope
== UNIT_FILE_USER
) {
4791 r
= user_config_home(user_home
);
4793 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4795 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4797 r
= user_runtime_dir(user_runtime
);
4799 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4801 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4804 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4806 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4811 static int cat_file(const char *filename
, bool newline
) {
4812 _cleanup_close_
int fd
;
4814 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4818 printf("%s%s# %s%s\n",
4819 newline
? "\n" : "",
4820 ansi_highlight_blue(),
4825 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4828 static int cat(int argc
, char *argv
[], void *userdata
) {
4829 _cleanup_free_
char *user_home
= NULL
;
4830 _cleanup_free_
char *user_runtime
= NULL
;
4831 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4832 _cleanup_strv_free_
char **names
= NULL
;
4838 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4839 log_error("Cannot remotely cat units.");
4843 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4847 r
= acquire_bus(BUS_MANAGER
, &bus
);
4851 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4853 return log_error_errno(r
, "Failed to expand names: %m");
4855 pager_open(arg_no_pager
, false);
4857 STRV_FOREACH(name
, names
) {
4858 _cleanup_free_
char *fragment_path
= NULL
;
4859 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4862 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4873 if (fragment_path
) {
4874 r
= cat_file(fragment_path
, false);
4876 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4879 STRV_FOREACH(path
, dropin_paths
) {
4880 r
= cat_file(*path
, path
== dropin_paths
);
4882 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4889 static int set_property(int argc
, char *argv
[], void *userdata
) {
4890 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4891 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4892 _cleanup_free_
char *n
= NULL
;
4897 polkit_agent_open_if_enabled();
4899 r
= acquire_bus(BUS_MANAGER
, &bus
);
4903 r
= sd_bus_message_new_method_call(
4906 "org.freedesktop.systemd1",
4907 "/org/freedesktop/systemd1",
4908 "org.freedesktop.systemd1.Manager",
4909 "SetUnitProperties");
4911 return bus_log_create_error(r
);
4913 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4915 return log_error_errno(r
, "Failed to mangle unit name: %m");
4917 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4919 return bus_log_create_error(r
);
4921 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4923 return bus_log_create_error(r
);
4925 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4926 r
= bus_append_unit_property_assignment(m
, *i
);
4931 r
= sd_bus_message_close_container(m
);
4933 return bus_log_create_error(r
);
4935 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4937 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4942 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4943 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4948 polkit_agent_open_if_enabled();
4950 r
= acquire_bus(BUS_MANAGER
, &bus
);
4954 if (arg_action
== ACTION_RELOAD
)
4956 else if (arg_action
== ACTION_REEXEC
)
4957 method
= "Reexecute";
4959 assert(arg_action
== ACTION_SYSTEMCTL
);
4962 streq(argv
[0], "clear-jobs") ||
4963 streq(argv
[0], "cancel") ? "ClearJobs" :
4964 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4965 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4966 streq(argv
[0], "halt") ? "Halt" :
4967 streq(argv
[0], "poweroff") ? "PowerOff" :
4968 streq(argv
[0], "reboot") ? "Reboot" :
4969 streq(argv
[0], "kexec") ? "KExec" :
4970 streq(argv
[0], "exit") ? "Exit" :
4971 /* "daemon-reload" */ "Reload";
4974 r
= sd_bus_call_method(
4976 "org.freedesktop.systemd1",
4977 "/org/freedesktop/systemd1",
4978 "org.freedesktop.systemd1.Manager",
4983 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4984 /* There's always a fallback possible for
4985 * legacy actions. */
4987 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4988 /* On reexecution, we expect a disconnect, not a
4992 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
4994 return r
< 0 ? r
: 0;
4997 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4998 _cleanup_strv_free_
char **names
= NULL
;
5004 return daemon_reload(argc
, argv
, userdata
);
5006 polkit_agent_open_if_enabled();
5008 r
= acquire_bus(BUS_MANAGER
, &bus
);
5012 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5014 return log_error_errno(r
, "Failed to expand names: %m");
5016 STRV_FOREACH(name
, names
) {
5017 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5019 q
= sd_bus_call_method(
5021 "org.freedesktop.systemd1",
5022 "/org/freedesktop/systemd1",
5023 "org.freedesktop.systemd1.Manager",
5029 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5038 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5039 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5040 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5045 pager_open(arg_no_pager
, false);
5047 r
= acquire_bus(BUS_MANAGER
, &bus
);
5051 r
= sd_bus_get_property(
5053 "org.freedesktop.systemd1",
5054 "/org/freedesktop/systemd1",
5055 "org.freedesktop.systemd1.Manager",
5061 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5063 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5065 return bus_log_parse_error(r
);
5067 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5070 return bus_log_parse_error(r
);
5072 r
= sd_bus_message_exit_container(reply
);
5074 return bus_log_parse_error(r
);
5079 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5080 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5081 _cleanup_free_
char *cmdline_init
= NULL
;
5082 const char *root
, *init
;
5086 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5087 log_error("Cannot switch root remotely.");
5091 if (argc
< 2 || argc
> 3) {
5092 log_error("Wrong number of arguments.");
5101 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5102 "init", &cmdline_init
,
5105 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5107 init
= cmdline_init
;
5114 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5116 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5117 root_init_path
= strjoina(root
, "/", init
);
5119 /* If the passed init is actually the same as the
5120 * systemd binary, then let's suppress it. */
5121 if (files_same(root_init_path
, root_systemd_path
) > 0)
5125 r
= acquire_bus(BUS_MANAGER
, &bus
);
5129 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5131 r
= sd_bus_call_method(
5133 "org.freedesktop.systemd1",
5134 "/org/freedesktop/systemd1",
5135 "org.freedesktop.systemd1.Manager",
5141 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5146 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5147 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5148 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5156 polkit_agent_open_if_enabled();
5158 r
= acquire_bus(BUS_MANAGER
, &bus
);
5162 method
= streq(argv
[0], "set-environment")
5164 : "UnsetEnvironment";
5166 r
= sd_bus_message_new_method_call(
5169 "org.freedesktop.systemd1",
5170 "/org/freedesktop/systemd1",
5171 "org.freedesktop.systemd1.Manager",
5174 return bus_log_create_error(r
);
5176 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5178 return bus_log_create_error(r
);
5180 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5182 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5187 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5188 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5189 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5193 polkit_agent_open_if_enabled();
5195 r
= acquire_bus(BUS_MANAGER
, &bus
);
5199 r
= sd_bus_message_new_method_call(
5202 "org.freedesktop.systemd1",
5203 "/org/freedesktop/systemd1",
5204 "org.freedesktop.systemd1.Manager",
5207 return bus_log_create_error(r
);
5210 r
= sd_bus_message_append_strv(m
, environ
);
5214 r
= sd_bus_message_open_container(m
, 'a', "s");
5216 return bus_log_create_error(r
);
5218 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5220 if (!env_name_is_valid(*a
)) {
5221 log_error("Not a valid environment variable name: %s", *a
);
5225 STRV_FOREACH(b
, environ
) {
5228 eq
= startswith(*b
, *a
);
5229 if (eq
&& *eq
== '=') {
5231 r
= sd_bus_message_append(m
, "s", *b
);
5233 return bus_log_create_error(r
);
5240 r
= sd_bus_message_close_container(m
);
5243 return bus_log_create_error(r
);
5245 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5247 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5252 static int enable_sysv_units(const char *verb
, char **args
) {
5255 #if defined(HAVE_SYSV_COMPAT)
5257 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5259 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5262 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5265 if (!STR_IN_SET(verb
,
5271 /* Processes all SysV units, and reshuffles the array so that
5272 * afterwards only the native units remain */
5274 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5281 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5282 bool found_native
= false, found_sysv
;
5284 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5292 if (!endswith(name
, ".service"))
5295 if (path_is_absolute(name
))
5298 STRV_FOREACH(k
, paths
.unit_path
) {
5299 _cleanup_free_
char *path
= NULL
;
5301 path
= path_join(arg_root
, *k
, name
);
5305 found_native
= access(path
, F_OK
) >= 0;
5310 /* If we have both a native unit and a SysV script,
5311 * enable/disable them both (below); for is-enabled, prefer the
5313 if (found_native
&& streq(verb
, "is-enabled"))
5316 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5320 p
[strlen(p
) - strlen(".service")] = 0;
5321 found_sysv
= access(p
, F_OK
) >= 0;
5326 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5328 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5330 if (!isempty(arg_root
))
5331 argv
[c
++] = q
= strappend("--root=", arg_root
);
5334 argv
[c
++] = basename(p
);
5337 l
= strv_join((char**)argv
, " ");
5341 log_info("Executing %s", l
);
5345 return log_error_errno(errno
, "Failed to fork: %m");
5346 else if (pid
== 0) {
5349 (void) reset_all_signal_handlers();
5350 (void) reset_signal_mask();
5352 execv(argv
[0], (char**) argv
);
5353 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5354 _exit(EXIT_FAILURE
);
5357 j
= wait_for_terminate(pid
, &status
);
5359 log_error_errno(j
, "Failed to wait for child: %m");
5363 if (status
.si_code
== CLD_EXITED
) {
5364 if (streq(verb
, "is-enabled")) {
5365 if (status
.si_status
== 0) {
5374 } else if (status
.si_status
!= 0)
5382 /* Remove this entry, so that we don't try enabling it as native unit */
5385 assert(args
[f
] == name
);
5386 strv_remove(args
, name
);
5393 static int mangle_names(char **original_names
, char ***mangled_names
) {
5394 char **i
, **l
, **name
;
5397 l
= i
= new(char*, strv_length(original_names
) + 1);
5401 STRV_FOREACH(name
, original_names
) {
5403 /* When enabling units qualified path names are OK,
5404 * too, hence allow them explicitly. */
5406 if (is_path(*name
)) {
5413 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5416 return log_error_errno(r
, "Failed to mangle unit name: %m");
5429 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5430 _cleanup_strv_free_
char **names
= NULL
;
5431 const char *verb
= argv
[0];
5432 UnitFileChange
*changes
= NULL
;
5433 unsigned n_changes
= 0;
5434 int carries_install_info
= -1;
5440 r
= mangle_names(strv_skip(argv
, 1), &names
);
5444 r
= enable_sysv_units(verb
, names
);
5448 /* If the operation was fully executed by the SysV compat,
5449 * let's finish early */
5450 if (strv_isempty(names
))
5453 if (install_client_side()) {
5454 if (streq(verb
, "enable")) {
5455 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5456 carries_install_info
= r
;
5457 } else if (streq(verb
, "disable"))
5458 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5459 else if (streq(verb
, "reenable")) {
5460 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5461 carries_install_info
= r
;
5462 } else if (streq(verb
, "link"))
5463 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5464 else if (streq(verb
, "preset")) {
5465 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5466 carries_install_info
= r
;
5467 } else if (streq(verb
, "mask"))
5468 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5469 else if (streq(verb
, "unmask"))
5470 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5472 assert_not_reached("Unknown verb");
5474 if (r
== -ESHUTDOWN
)
5475 return log_error_errno(r
, "Unit file is masked.");
5477 return log_error_errno(r
, "Operation failed: %m");
5480 dump_unit_file_changes(changes
, n_changes
);
5484 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5485 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5486 int expect_carries_install_info
= false;
5487 bool send_force
= true, send_preset_mode
= false;
5491 polkit_agent_open_if_enabled();
5493 r
= acquire_bus(BUS_MANAGER
, &bus
);
5497 if (streq(verb
, "enable")) {
5498 method
= "EnableUnitFiles";
5499 expect_carries_install_info
= true;
5500 } else if (streq(verb
, "disable")) {
5501 method
= "DisableUnitFiles";
5503 } else if (streq(verb
, "reenable")) {
5504 method
= "ReenableUnitFiles";
5505 expect_carries_install_info
= true;
5506 } else if (streq(verb
, "link"))
5507 method
= "LinkUnitFiles";
5508 else if (streq(verb
, "preset")) {
5510 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5511 method
= "PresetUnitFilesWithMode";
5512 send_preset_mode
= true;
5514 method
= "PresetUnitFiles";
5516 expect_carries_install_info
= true;
5517 } else if (streq(verb
, "mask"))
5518 method
= "MaskUnitFiles";
5519 else if (streq(verb
, "unmask")) {
5520 method
= "UnmaskUnitFiles";
5523 assert_not_reached("Unknown verb");
5525 r
= sd_bus_message_new_method_call(
5528 "org.freedesktop.systemd1",
5529 "/org/freedesktop/systemd1",
5530 "org.freedesktop.systemd1.Manager",
5533 return bus_log_create_error(r
);
5535 r
= sd_bus_message_append_strv(m
, names
);
5537 return bus_log_create_error(r
);
5539 if (send_preset_mode
) {
5540 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5542 return bus_log_create_error(r
);
5545 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5547 return bus_log_create_error(r
);
5550 r
= sd_bus_message_append(m
, "b", arg_force
);
5552 return bus_log_create_error(r
);
5555 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5557 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5559 if (expect_carries_install_info
) {
5560 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5562 return bus_log_parse_error(r
);
5565 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5569 /* Try to reload if enabled */
5571 r
= daemon_reload(argc
, argv
, userdata
);
5576 if (carries_install_info
== 0)
5577 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5578 "using systemctl.\n"
5579 "Possible reasons for having this kind of units are:\n"
5580 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5581 " .wants/ or .requires/ directory.\n"
5582 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5583 " a requirement dependency on it.\n"
5584 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5585 " D-Bus, udev, scripted systemctl call, ...).\n");
5587 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5588 char *new_args
[n_changes
+ 2];
5592 r
= acquire_bus(BUS_MANAGER
, &bus
);
5596 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5597 for (i
= 0; i
< n_changes
; i
++)
5598 new_args
[i
+ 1] = basename(changes
[i
].path
);
5599 new_args
[i
+ 1] = NULL
;
5601 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5605 unit_file_changes_free(changes
, n_changes
);
5610 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5611 _cleanup_strv_free_
char **names
= NULL
;
5612 _cleanup_free_
char *target
= NULL
;
5613 const char *verb
= argv
[0];
5620 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5622 return log_error_errno(r
, "Failed to mangle unit name: %m");
5624 r
= mangle_names(strv_skip(argv
, 2), &names
);
5628 if (streq(verb
, "add-wants"))
5630 else if (streq(verb
, "add-requires"))
5631 dep
= UNIT_REQUIRES
;
5633 assert_not_reached("Unknown verb");
5635 if (install_client_side()) {
5636 UnitFileChange
*changes
= NULL
;
5637 unsigned n_changes
= 0;
5639 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5640 if (r
== -ESHUTDOWN
)
5641 return log_error_errno(r
, "Unit file is masked.");
5643 return log_error_errno(r
, "Can't add dependency: %m");
5646 dump_unit_file_changes(changes
, n_changes
);
5648 unit_file_changes_free(changes
, n_changes
);
5651 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5652 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5655 polkit_agent_open_if_enabled();
5657 r
= acquire_bus(BUS_MANAGER
, &bus
);
5661 r
= sd_bus_message_new_method_call(
5664 "org.freedesktop.systemd1",
5665 "/org/freedesktop/systemd1",
5666 "org.freedesktop.systemd1.Manager",
5667 "AddDependencyUnitFiles");
5669 return bus_log_create_error(r
);
5671 r
= sd_bus_message_append_strv(m
, names
);
5673 return bus_log_create_error(r
);
5675 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5677 return bus_log_create_error(r
);
5679 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5681 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5683 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5688 r
= daemon_reload(argc
, argv
, userdata
);
5696 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5697 UnitFileChange
*changes
= NULL
;
5698 unsigned n_changes
= 0;
5701 if (install_client_side()) {
5703 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5705 log_error_errno(r
, "Operation failed: %m");
5710 dump_unit_file_changes(changes
, n_changes
);
5715 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5716 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5719 polkit_agent_open_if_enabled();
5721 r
= acquire_bus(BUS_MANAGER
, &bus
);
5725 r
= sd_bus_call_method(
5727 "org.freedesktop.systemd1",
5728 "/org/freedesktop/systemd1",
5729 "org.freedesktop.systemd1.Manager",
5730 "PresetAllUnitFiles",
5734 unit_file_preset_mode_to_string(arg_preset_mode
),
5738 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5740 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5745 r
= daemon_reload(argc
, argv
, userdata
);
5751 unit_file_changes_free(changes
, n_changes
);
5756 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5758 _cleanup_strv_free_
char **names
= NULL
;
5763 r
= mangle_names(strv_skip(argv
, 1), &names
);
5767 r
= enable_sysv_units(argv
[0], names
);
5773 if (install_client_side()) {
5775 STRV_FOREACH(name
, names
) {
5776 UnitFileState state
;
5778 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5780 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5784 UNIT_FILE_ENABLED_RUNTIME
,
5786 UNIT_FILE_INDIRECT
))
5790 puts(unit_file_state_to_string(state
));
5794 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5797 r
= acquire_bus(BUS_MANAGER
, &bus
);
5801 STRV_FOREACH(name
, names
) {
5802 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5805 r
= sd_bus_call_method(
5807 "org.freedesktop.systemd1",
5808 "/org/freedesktop/systemd1",
5809 "org.freedesktop.systemd1.Manager",
5815 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5817 r
= sd_bus_message_read(reply
, "s", &s
);
5819 return bus_log_parse_error(r
);
5821 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5832 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5833 _cleanup_free_
char *state
= NULL
;
5837 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5840 return EXIT_FAILURE
;
5843 r
= acquire_bus(BUS_MANAGER
, &bus
);
5847 r
= sd_bus_get_property_string(
5849 "org.freedesktop.systemd1",
5850 "/org/freedesktop/systemd1",
5851 "org.freedesktop.systemd1.Manager",
5864 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5867 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5868 _cleanup_free_
char *t
= NULL
;
5872 assert(original_path
);
5875 r
= tempfn_random(new_path
, NULL
, &t
);
5877 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5879 r
= mkdir_parents(new_path
, 0755);
5881 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5883 r
= copy_file(original_path
, t
, 0, 0644, 0);
5888 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5891 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5899 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5900 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5905 switch (arg_scope
) {
5906 case UNIT_FILE_SYSTEM
:
5907 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5909 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5911 case UNIT_FILE_GLOBAL
:
5912 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5914 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5916 case UNIT_FILE_USER
:
5918 assert(user_runtime
);
5920 path
= path_join(arg_root
, user_home
, name
);
5922 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5925 run
= path_join(arg_root
, user_runtime
, name
);
5929 assert_not_reached("Invalid scope");
5931 if (!path
|| (arg_runtime
&& !run
))
5935 if (access(path
, F_OK
) >= 0) {
5936 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5940 if (path2
&& access(path2
, F_OK
) >= 0) {
5941 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5955 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
) {
5956 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5960 assert(ret_new_path
);
5961 assert(ret_tmp_path
);
5963 ending
= strjoina(unit_name
, ".d/override.conf");
5964 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5968 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5974 *ret_new_path
= tmp_new_path
;
5975 *ret_tmp_path
= tmp_tmp_path
;
5980 static int unit_file_create_copy(
5981 const char *unit_name
,
5982 const char *fragment_path
,
5983 const char *user_home
,
5984 const char *user_runtime
,
5985 char **ret_new_path
,
5986 char **ret_tmp_path
) {
5988 char *tmp_new_path
, *tmp_tmp_path
;
5991 assert(fragment_path
);
5993 assert(ret_new_path
);
5994 assert(ret_tmp_path
);
5996 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
6000 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6003 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6008 if (response
!= 'y') {
6009 log_warning("%s ignored", unit_name
);
6015 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6017 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6022 *ret_new_path
= tmp_new_path
;
6023 *ret_tmp_path
= tmp_tmp_path
;
6028 static int run_editor(char **paths
) {
6036 return log_error_errno(errno
, "Failed to fork: %m");
6040 char *editor
, **editor_args
= NULL
;
6041 char **tmp_path
, **original_path
, *p
;
6042 unsigned n_editor_args
= 0, i
= 1;
6045 (void) reset_all_signal_handlers();
6046 (void) reset_signal_mask();
6048 argc
= strv_length(paths
)/2 + 1;
6050 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6051 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6052 * we try to execute well known editors
6054 editor
= getenv("SYSTEMD_EDITOR");
6056 editor
= getenv("EDITOR");
6058 editor
= getenv("VISUAL");
6060 if (!isempty(editor
)) {
6061 editor_args
= strv_split(editor
, WHITESPACE
);
6064 _exit(EXIT_FAILURE
);
6066 n_editor_args
= strv_length(editor_args
);
6067 argc
+= n_editor_args
- 1;
6069 args
= newa(const char*, argc
+ 1);
6071 if (n_editor_args
> 0) {
6072 args
[0] = editor_args
[0];
6073 for (; i
< n_editor_args
; i
++)
6074 args
[i
] = editor_args
[i
];
6077 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6078 args
[i
] = *tmp_path
;
6083 if (n_editor_args
> 0)
6084 execvp(args
[0], (char* const*) args
);
6086 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6088 execvp(p
, (char* const*) args
);
6089 /* We do not fail if the editor doesn't exist
6090 * because we want to try each one of them before
6093 if (errno
!= ENOENT
) {
6094 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6095 _exit(EXIT_FAILURE
);
6099 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6100 _exit(EXIT_FAILURE
);
6103 r
= wait_for_terminate_and_warn("editor", pid
, true);
6105 return log_error_errno(r
, "Failed to wait for child: %m");
6110 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6111 _cleanup_free_
char *user_home
= NULL
;
6112 _cleanup_free_
char *user_runtime
= NULL
;
6113 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6120 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6124 STRV_FOREACH(name
, names
) {
6125 _cleanup_free_
char *path
= NULL
;
6126 char *new_path
, *tmp_path
;
6128 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6134 // FIXME: support units with path==NULL (no FragmentPath)
6135 log_error("No fragment exists for %s.", *name
);
6140 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6142 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6146 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6154 static int edit(int argc
, char *argv
[], void *userdata
) {
6155 _cleanup_strv_free_
char **names
= NULL
;
6156 _cleanup_strv_free_
char **paths
= NULL
;
6157 char **original
, **tmp
;
6162 log_error("Cannot edit units if not on a tty.");
6166 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6167 log_error("Cannot edit units remotely.");
6171 r
= acquire_bus(BUS_MANAGER
, &bus
);
6175 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6177 return log_error_errno(r
, "Failed to expand names: %m");
6179 r
= find_paths_to_edit(bus
, names
, &paths
);
6183 if (strv_isempty(paths
))
6186 r
= run_editor(paths
);
6190 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6191 /* If the temporary file is empty we ignore it. It's
6192 * useful if the user wants to cancel its modification
6194 if (null_or_empty_path(*tmp
)) {
6195 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6199 r
= rename(*tmp
, *original
);
6201 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6208 if (!arg_no_reload
&& !install_client_side())
6209 r
= daemon_reload(argc
, argv
, userdata
);
6212 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6213 (void) unlink(*tmp
);
6215 /* Removing empty dropin dirs */
6217 _cleanup_free_
char *dir
;
6219 dir
= dirname_malloc(*original
);
6223 /* no need to check if the dir is empty, rmdir
6224 * does nothing if it is not the case.
6233 static void systemctl_help(void) {
6235 pager_open(arg_no_pager
, false);
6237 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6238 "Query or send control commands to the systemd manager.\n\n"
6239 " -h --help Show this help\n"
6240 " --version Show package version\n"
6241 " --system Connect to system manager\n"
6242 " --user Connect to user service manager\n"
6243 " -H --host=[USER@]HOST\n"
6244 " Operate on remote host\n"
6245 " -M --machine=CONTAINER\n"
6246 " Operate on local container\n"
6247 " -t --type=TYPE List units of a particular type\n"
6248 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6249 " -p --property=NAME Show only properties by this name\n"
6250 " -a --all Show all loaded units/properties, including dead/empty\n"
6251 " ones. To list all units installed on the system, use\n"
6252 " the 'list-unit-files' command instead.\n"
6253 " -l --full Don't ellipsize unit names on output\n"
6254 " -r --recursive Show unit list of host and local containers\n"
6255 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6256 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6257 " queueing a new job\n"
6258 " --show-types When showing sockets, explicitly show their type\n"
6259 " --value When showing properties, only print the value\n"
6260 " -i --ignore-inhibitors\n"
6261 " When shutting down or sleeping, ignore inhibitors\n"
6262 " --kill-who=WHO Who to send signal to\n"
6263 " -s --signal=SIGNAL Which signal to send\n"
6264 " --now Start or stop unit in addition to enabling or disabling it\n"
6265 " -q --quiet Suppress output\n"
6266 " --no-block Do not wait until operation finished\n"
6267 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6268 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6269 " --no-legend Do not print a legend (column headers and hints)\n"
6270 " --no-pager Do not pipe output into a pager\n"
6271 " --no-ask-password\n"
6272 " Do not ask for system passwords\n"
6273 " --global Enable/disable unit files globally\n"
6274 " --runtime Enable unit files only temporarily until next reboot\n"
6275 " -f --force When enabling unit files, override existing symlinks\n"
6276 " When shutting down, execute action immediately\n"
6277 " --preset-mode= Apply only enable, only disable, or all presets\n"
6278 " --root=PATH Enable unit files in the specified root directory\n"
6279 " -n --lines=INTEGER Number of journal entries to show\n"
6280 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6281 " short-precise, short-monotonic, verbose,\n"
6282 " export, json, json-pretty, json-sse, cat)\n"
6283 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6284 " --plain Print unit dependencies as a list instead of a tree\n\n"
6286 " list-units [PATTERN...] List loaded units\n"
6287 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6288 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6289 " start NAME... Start (activate) one or more units\n"
6290 " stop NAME... Stop (deactivate) one or more units\n"
6291 " reload NAME... Reload one or more units\n"
6292 " restart NAME... Start or restart one or more units\n"
6293 " try-restart NAME... Restart one or more units if active\n"
6294 " reload-or-restart NAME... Reload one or more units if possible,\n"
6295 " otherwise start or restart\n"
6296 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6297 " if supported, otherwise restart\n"
6298 " isolate NAME Start one unit and stop all others\n"
6299 " kill NAME... Send signal to processes of a unit\n"
6300 " is-active PATTERN... Check whether units are active\n"
6301 " is-failed PATTERN... Check whether units are failed\n"
6302 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6303 " show [PATTERN...|JOB...] Show properties of one or more\n"
6304 " units/jobs or the manager\n"
6305 " cat PATTERN... Show files and drop-ins of one or more units\n"
6306 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6307 " help PATTERN...|PID... Show manual for one or more units\n"
6308 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6310 " list-dependencies [NAME] Recursively show units which are required\n"
6311 " or wanted by this unit or by which this\n"
6312 " unit is required or wanted\n\n"
6313 "Unit File Commands:\n"
6314 " list-unit-files [PATTERN...] List installed unit files\n"
6315 " enable NAME... Enable one or more unit files\n"
6316 " disable NAME... Disable one or more unit files\n"
6317 " reenable NAME... Reenable one or more unit files\n"
6318 " preset NAME... Enable/disable one or more unit files\n"
6319 " based on preset configuration\n"
6320 " preset-all Enable/disable all unit files based on\n"
6321 " preset configuration\n"
6322 " is-enabled NAME... Check whether unit files are enabled\n"
6323 " mask NAME... Mask one or more units\n"
6324 " unmask NAME... Unmask one or more units\n"
6325 " link PATH... Link one or more units files into\n"
6326 " the search path\n"
6327 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6328 " on specified one or more units\n"
6329 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6330 " on specified one or more units\n"
6331 " edit NAME... Edit one or more unit files\n"
6332 " get-default Get the name of the default target\n"
6333 " set-default NAME Set the default target\n\n"
6334 "Machine Commands:\n"
6335 " list-machines [PATTERN...] List local containers and host\n\n"
6337 " list-jobs [PATTERN...] List jobs\n"
6338 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6339 "Environment Commands:\n"
6340 " show-environment Dump environment\n"
6341 " set-environment NAME=VALUE... Set one or more environment variables\n"
6342 " unset-environment NAME... Unset one or more environment variables\n"
6343 " import-environment [NAME...] Import all or some environment variables\n\n"
6344 "Manager Lifecycle Commands:\n"
6345 " daemon-reload Reload systemd manager configuration\n"
6346 " daemon-reexec Reexecute systemd manager\n\n"
6347 "System Commands:\n"
6348 " is-system-running Check whether system is fully running\n"
6349 " default Enter system default mode\n"
6350 " rescue Enter system rescue mode\n"
6351 " emergency Enter system emergency mode\n"
6352 " halt Shut down and halt the system\n"
6353 " poweroff Shut down and power-off the system\n"
6354 " reboot [ARG] Shut down and reboot the system\n"
6355 " kexec Shut down and reboot the system with kexec\n"
6356 " exit [EXIT_CODE] Request user instance or container exit\n"
6357 " switch-root ROOT [INIT] Change to a different root file system\n"
6358 " suspend Suspend the system\n"
6359 " hibernate Hibernate the system\n"
6360 " hybrid-sleep Hibernate and suspend the system\n",
6361 program_invocation_short_name
);
6364 static void halt_help(void) {
6365 printf("%s [OPTIONS...]%s\n\n"
6366 "%s the system.\n\n"
6367 " --help Show this help\n"
6368 " --halt Halt the machine\n"
6369 " -p --poweroff Switch off the machine\n"
6370 " --reboot Reboot the machine\n"
6371 " -f --force Force immediate halt/power-off/reboot\n"
6372 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6373 " -d --no-wtmp Don't write wtmp record\n"
6374 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6375 program_invocation_short_name
,
6376 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6377 arg_action
== ACTION_REBOOT
? "Reboot" :
6378 arg_action
== ACTION_POWEROFF
? "Power off" :
6382 static void shutdown_help(void) {
6383 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6384 "Shut down the system.\n\n"
6385 " --help Show this help\n"
6386 " -H --halt Halt the machine\n"
6387 " -P --poweroff Power-off the machine\n"
6388 " -r --reboot Reboot the machine\n"
6389 " -h Equivalent to --poweroff, overridden by --halt\n"
6390 " -k Don't halt/power-off/reboot, just send warnings\n"
6391 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6392 " -c Cancel a pending shutdown\n",
6393 program_invocation_short_name
);
6396 static void telinit_help(void) {
6397 printf("%s [OPTIONS...] {COMMAND}\n\n"
6398 "Send control commands to the init daemon.\n\n"
6399 " --help Show this help\n"
6400 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6402 " 0 Power-off the machine\n"
6403 " 6 Reboot the machine\n"
6404 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6405 " 1, s, S Enter rescue mode\n"
6406 " q, Q Reload init daemon configuration\n"
6407 " u, U Reexecute init daemon\n",
6408 program_invocation_short_name
);
6411 static void runlevel_help(void) {
6412 printf("%s [OPTIONS...]\n\n"
6413 "Prints the previous and current runlevel of the init system.\n\n"
6414 " --help Show this help\n",
6415 program_invocation_short_name
);
6418 static void help_types(void) {
6422 puts("Available unit types:");
6423 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6424 puts(unit_type_to_string(i
));
6427 static void help_states(void) {
6431 puts("Available unit load states:");
6432 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6433 puts(unit_load_state_to_string(i
));
6436 puts("\nAvailable unit active states:");
6437 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6438 puts(unit_active_state_to_string(i
));
6441 puts("\nAvailable automount unit substates:");
6442 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6443 puts(automount_state_to_string(i
));
6446 puts("\nAvailable busname unit substates:");
6447 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6448 puts(busname_state_to_string(i
));
6451 puts("\nAvailable device unit substates:");
6452 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6453 puts(device_state_to_string(i
));
6456 puts("\nAvailable mount unit substates:");
6457 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6458 puts(mount_state_to_string(i
));
6461 puts("\nAvailable path unit substates:");
6462 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6463 puts(path_state_to_string(i
));
6466 puts("\nAvailable scope unit substates:");
6467 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6468 puts(scope_state_to_string(i
));
6471 puts("\nAvailable service unit substates:");
6472 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6473 puts(service_state_to_string(i
));
6476 puts("\nAvailable slice unit substates:");
6477 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6478 puts(slice_state_to_string(i
));
6481 puts("\nAvailable socket unit substates:");
6482 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6483 puts(socket_state_to_string(i
));
6486 puts("\nAvailable swap unit substates:");
6487 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6488 puts(swap_state_to_string(i
));
6491 puts("\nAvailable target unit substates:");
6492 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6493 puts(target_state_to_string(i
));
6496 puts("\nAvailable timer unit substates:");
6497 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6498 puts(timer_state_to_string(i
));
6501 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6510 ARG_IGNORE_DEPENDENCIES
,
6523 ARG_NO_ASK_PASSWORD
,
6536 static const struct option options
[] = {
6537 { "help", no_argument
, NULL
, 'h' },
6538 { "version", no_argument
, NULL
, ARG_VERSION
},
6539 { "type", required_argument
, NULL
, 't' },
6540 { "property", required_argument
, NULL
, 'p' },
6541 { "all", no_argument
, NULL
, 'a' },
6542 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6543 { "after", no_argument
, NULL
, ARG_AFTER
},
6544 { "before", no_argument
, NULL
, ARG_BEFORE
},
6545 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6546 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6547 { "full", no_argument
, NULL
, 'l' },
6548 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6549 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6550 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6551 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6552 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6553 { "value", no_argument
, NULL
, ARG_VALUE
},
6554 { "user", no_argument
, NULL
, ARG_USER
},
6555 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6556 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6557 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6558 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6559 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6560 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6561 { "quiet", no_argument
, NULL
, 'q' },
6562 { "root", required_argument
, NULL
, ARG_ROOT
},
6563 { "force", no_argument
, NULL
, ARG_FORCE
},
6564 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6565 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6566 { "signal", required_argument
, NULL
, 's' },
6567 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6568 { "host", required_argument
, NULL
, 'H' },
6569 { "machine", required_argument
, NULL
, 'M' },
6570 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6571 { "lines", required_argument
, NULL
, 'n' },
6572 { "output", required_argument
, NULL
, 'o' },
6573 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6574 { "state", required_argument
, NULL
, ARG_STATE
},
6575 { "recursive", no_argument
, NULL
, 'r' },
6576 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6577 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6578 { "now", no_argument
, NULL
, ARG_NOW
},
6579 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6589 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6590 arg_ask_password
= true;
6592 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6604 if (isempty(optarg
)) {
6605 log_error("--type requires arguments.");
6611 _cleanup_free_
char *type
= NULL
;
6613 r
= extract_first_word(&p
, &type
, ",", 0);
6615 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6620 if (streq(type
, "help")) {
6625 if (unit_type_from_string(type
) >= 0) {
6626 if (strv_push(&arg_types
, type
) < 0)
6632 /* It's much nicer to use --state= for
6633 * load states, but let's support this
6634 * in --types= too for compatibility
6635 * with old versions */
6636 if (unit_load_state_from_string(type
) >= 0) {
6637 if (strv_push(&arg_states
, type
) < 0)
6643 log_error("Unknown unit type or load state '%s'.", type
);
6644 log_info("Use -t help to see a list of allowed values.");
6652 /* Make sure that if the empty property list
6653 was specified, we won't show any properties. */
6654 if (isempty(optarg
) && !arg_properties
) {
6655 arg_properties
= new0(char*, 1);
6656 if (!arg_properties
)
6661 _cleanup_free_
char *prop
= NULL
;
6663 r
= extract_first_word(&p
, &prop
, ",", 0);
6665 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6670 if (strv_push(&arg_properties
, prop
) < 0)
6677 /* If the user asked for a particular
6678 * property, show it to him, even if it is
6690 arg_dependency
= DEPENDENCY_REVERSE
;
6694 arg_dependency
= DEPENDENCY_AFTER
;
6698 arg_dependency
= DEPENDENCY_BEFORE
;
6701 case ARG_SHOW_TYPES
:
6702 arg_show_types
= true;
6710 arg_job_mode
= optarg
;
6714 arg_job_mode
= "fail";
6717 case ARG_IRREVERSIBLE
:
6718 arg_job_mode
= "replace-irreversibly";
6721 case ARG_IGNORE_DEPENDENCIES
:
6722 arg_job_mode
= "ignore-dependencies";
6726 arg_scope
= UNIT_FILE_USER
;
6730 arg_scope
= UNIT_FILE_SYSTEM
;
6734 arg_scope
= UNIT_FILE_GLOBAL
;
6738 arg_no_block
= true;
6742 arg_no_legend
= true;
6746 arg_no_pager
= true;
6754 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6764 if (strv_extend(&arg_states
, "failed") < 0)
6782 arg_no_reload
= true;
6786 arg_kill_who
= optarg
;
6790 arg_signal
= signal_from_string_try_harder(optarg
);
6791 if (arg_signal
< 0) {
6792 log_error("Failed to parse signal string %s.", optarg
);
6797 case ARG_NO_ASK_PASSWORD
:
6798 arg_ask_password
= false;
6802 arg_transport
= BUS_TRANSPORT_REMOTE
;
6807 arg_transport
= BUS_TRANSPORT_MACHINE
;
6816 if (safe_atou(optarg
, &arg_lines
) < 0) {
6817 log_error("Failed to parse lines '%s'", optarg
);
6823 arg_output
= output_mode_from_string(optarg
);
6824 if (arg_output
< 0) {
6825 log_error("Unknown output '%s'.", optarg
);
6831 arg_ignore_inhibitors
= true;
6838 case ARG_FIRMWARE_SETUP
:
6839 arg_firmware_setup
= true;
6843 if (isempty(optarg
)) {
6844 log_error("--signal requires arguments.");
6850 _cleanup_free_
char *s
= NULL
;
6852 r
= extract_first_word(&p
, &s
, ",", 0);
6854 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6859 if (streq(s
, "help")) {
6864 if (strv_push(&arg_states
, s
) < 0)
6873 if (geteuid() != 0) {
6874 log_error("--recursive requires root privileges.");
6878 arg_recursive
= true;
6881 case ARG_PRESET_MODE
:
6883 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6884 if (arg_preset_mode
< 0) {
6885 log_error("Failed to parse preset mode: %s.", optarg
);
6896 if (strv_extend(&arg_wall
, optarg
) < 0)
6904 assert_not_reached("Unhandled option");
6907 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6908 log_error("Cannot access user instance remotely.");
6915 static int halt_parse_argv(int argc
, char *argv
[]) {
6924 static const struct option options
[] = {
6925 { "help", no_argument
, NULL
, ARG_HELP
},
6926 { "halt", no_argument
, NULL
, ARG_HALT
},
6927 { "poweroff", no_argument
, NULL
, 'p' },
6928 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6929 { "force", no_argument
, NULL
, 'f' },
6930 { "wtmp-only", no_argument
, NULL
, 'w' },
6931 { "no-wtmp", no_argument
, NULL
, 'd' },
6932 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6941 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6942 if (runlevel
== '0' || runlevel
== '6')
6945 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6953 arg_action
= ACTION_HALT
;
6957 if (arg_action
!= ACTION_REBOOT
)
6958 arg_action
= ACTION_POWEROFF
;
6962 arg_action
= ACTION_REBOOT
;
6984 /* Compatibility nops */
6991 assert_not_reached("Unhandled option");
6994 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6995 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6998 } else if (optind
< argc
) {
6999 log_error("Too many arguments.");
7006 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7010 if (streq(t
, "now"))
7012 else if (!strchr(t
, ':')) {
7015 if (safe_atou64(t
, &u
) < 0)
7018 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7027 hour
= strtol(t
, &e
, 10);
7028 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7031 minute
= strtol(e
+1, &e
, 10);
7032 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7035 n
= now(CLOCK_REALTIME
);
7036 s
= (time_t) (n
/ USEC_PER_SEC
);
7038 assert_se(localtime_r(&s
, &tm
));
7040 tm
.tm_hour
= (int) hour
;
7041 tm
.tm_min
= (int) minute
;
7044 assert_se(s
= mktime(&tm
));
7046 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7049 *_u
+= USEC_PER_DAY
;
7055 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7062 static const struct option options
[] = {
7063 { "help", no_argument
, NULL
, ARG_HELP
},
7064 { "halt", no_argument
, NULL
, 'H' },
7065 { "poweroff", no_argument
, NULL
, 'P' },
7066 { "reboot", no_argument
, NULL
, 'r' },
7067 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7068 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7078 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7086 arg_action
= ACTION_HALT
;
7090 arg_action
= ACTION_POWEROFF
;
7095 arg_action
= ACTION_KEXEC
;
7097 arg_action
= ACTION_REBOOT
;
7101 arg_action
= ACTION_KEXEC
;
7105 if (arg_action
!= ACTION_HALT
)
7106 arg_action
= ACTION_POWEROFF
;
7121 /* Compatibility nops */
7125 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7132 assert_not_reached("Unhandled option");
7135 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7136 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7138 log_error("Failed to parse time specification: %s", argv
[optind
]);
7142 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7144 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7145 /* No time argument for shutdown cancel */
7146 wall
= argv
+ optind
;
7147 else if (argc
> optind
+ 1)
7148 /* We skip the time argument */
7149 wall
= argv
+ optind
+ 1;
7152 arg_wall
= strv_copy(wall
);
7162 static int telinit_parse_argv(int argc
, char *argv
[]) {
7169 static const struct option options
[] = {
7170 { "help", no_argument
, NULL
, ARG_HELP
},
7171 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7175 static const struct {
7179 { '0', ACTION_POWEROFF
},
7180 { '6', ACTION_REBOOT
},
7181 { '1', ACTION_RESCUE
},
7182 { '2', ACTION_RUNLEVEL2
},
7183 { '3', ACTION_RUNLEVEL3
},
7184 { '4', ACTION_RUNLEVEL4
},
7185 { '5', ACTION_RUNLEVEL5
},
7186 { 's', ACTION_RESCUE
},
7187 { 'S', ACTION_RESCUE
},
7188 { 'q', ACTION_RELOAD
},
7189 { 'Q', ACTION_RELOAD
},
7190 { 'u', ACTION_REEXEC
},
7191 { 'U', ACTION_REEXEC
}
7200 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7215 assert_not_reached("Unhandled option");
7218 if (optind
>= argc
) {
7219 log_error("%s: required argument missing.", program_invocation_short_name
);
7223 if (optind
+ 1 < argc
) {
7224 log_error("Too many arguments.");
7228 if (strlen(argv
[optind
]) != 1) {
7229 log_error("Expected single character argument.");
7233 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7234 if (table
[i
].from
== argv
[optind
][0])
7237 if (i
>= ELEMENTSOF(table
)) {
7238 log_error("Unknown command '%s'.", argv
[optind
]);
7242 arg_action
= table
[i
].to
;
7249 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7255 static const struct option options
[] = {
7256 { "help", no_argument
, NULL
, ARG_HELP
},
7265 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7276 assert_not_reached("Unhandled option");
7279 if (optind
< argc
) {
7280 log_error("Too many arguments.");
7287 static int parse_argv(int argc
, char *argv
[]) {
7291 if (program_invocation_short_name
) {
7293 if (strstr(program_invocation_short_name
, "halt")) {
7294 arg_action
= ACTION_HALT
;
7295 return halt_parse_argv(argc
, argv
);
7296 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7297 arg_action
= ACTION_POWEROFF
;
7298 return halt_parse_argv(argc
, argv
);
7299 } else if (strstr(program_invocation_short_name
, "reboot")) {
7301 arg_action
= ACTION_KEXEC
;
7303 arg_action
= ACTION_REBOOT
;
7304 return halt_parse_argv(argc
, argv
);
7305 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7306 arg_action
= ACTION_POWEROFF
;
7307 return shutdown_parse_argv(argc
, argv
);
7308 } else if (strstr(program_invocation_short_name
, "init")) {
7310 if (sd_booted() > 0) {
7311 arg_action
= _ACTION_INVALID
;
7312 return telinit_parse_argv(argc
, argv
);
7314 /* Hmm, so some other init system is
7315 * running, we need to forward this
7316 * request to it. For now we simply
7317 * guess that it is Upstart. */
7319 execv(TELINIT
, argv
);
7321 log_error("Couldn't find an alternative telinit implementation to spawn.");
7325 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7326 arg_action
= ACTION_RUNLEVEL
;
7327 return runlevel_parse_argv(argc
, argv
);
7331 arg_action
= ACTION_SYSTEMCTL
;
7332 return systemctl_parse_argv(argc
, argv
);
7335 #ifdef HAVE_SYSV_COMPAT
7336 _pure_
static int action_to_runlevel(void) {
7338 static const char table
[_ACTION_MAX
] = {
7339 [ACTION_HALT
] = '0',
7340 [ACTION_POWEROFF
] = '0',
7341 [ACTION_REBOOT
] = '6',
7342 [ACTION_RUNLEVEL2
] = '2',
7343 [ACTION_RUNLEVEL3
] = '3',
7344 [ACTION_RUNLEVEL4
] = '4',
7345 [ACTION_RUNLEVEL5
] = '5',
7346 [ACTION_RESCUE
] = '1'
7349 assert(arg_action
< _ACTION_MAX
);
7351 return table
[arg_action
];
7355 static int talk_initctl(void) {
7356 #ifdef HAVE_SYSV_COMPAT
7357 struct init_request request
= {
7358 .magic
= INIT_MAGIC
,
7360 .cmd
= INIT_CMD_RUNLVL
7363 _cleanup_close_
int fd
= -1;
7367 rl
= action_to_runlevel();
7371 request
.runlevel
= rl
;
7373 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7375 if (errno
== ENOENT
)
7378 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7381 r
= loop_write(fd
, &request
, sizeof(request
), false);
7383 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7391 static int systemctl_main(int argc
, char *argv
[]) {
7393 static const Verb verbs
[] = {
7394 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7395 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7396 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7397 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7398 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7399 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7400 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7401 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7402 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7403 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7404 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7405 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7406 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7407 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7408 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7409 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7410 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7411 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7412 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7413 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7414 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7415 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7416 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7417 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7418 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7419 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7420 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7421 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7422 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7423 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7424 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7425 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7426 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7427 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7428 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7429 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7430 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7431 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7432 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7433 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7434 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7435 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7436 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7437 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7438 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7439 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7440 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7441 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7442 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7443 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7444 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7445 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7446 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7447 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7448 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7449 { "link", 2, VERB_ANY
, 0, enable_unit
},
7450 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7451 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7452 { "set-default", 2, 2, 0, set_default
},
7453 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7454 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7455 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7456 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7457 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7458 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7462 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7465 static int reload_with_fallback(void) {
7467 /* First, try systemd via D-Bus. */
7468 if (daemon_reload(0, NULL
, NULL
) >= 0)
7471 /* Nothing else worked, so let's try signals */
7472 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7474 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7475 return log_error_errno(errno
, "kill() failed: %m");
7480 static int start_with_fallback(void) {
7482 /* First, try systemd via D-Bus. */
7483 if (start_unit(0, NULL
, NULL
) >= 0)
7486 /* Nothing else worked, so let's try
7488 if (talk_initctl() > 0)
7491 log_error("Failed to talk to init daemon.");
7495 static int halt_now(enum action a
) {
7497 /* The kernel will automaticall flush ATA disks and suchlike
7498 * on reboot(), but the file systems need to be synce'd
7499 * explicitly in advance. */
7502 /* Make sure C-A-D is handled by the kernel from this point
7504 (void) reboot(RB_ENABLE_CAD
);
7509 log_info("Halting.");
7510 (void) reboot(RB_HALT_SYSTEM
);
7513 case ACTION_POWEROFF
:
7514 log_info("Powering off.");
7515 (void) reboot(RB_POWER_OFF
);
7519 case ACTION_REBOOT
: {
7520 _cleanup_free_
char *param
= NULL
;
7522 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7523 log_info("Rebooting with argument '%s'.", param
);
7524 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7527 log_info("Rebooting.");
7528 (void) reboot(RB_AUTOBOOT
);
7533 assert_not_reached("Unknown action.");
7537 static int logind_schedule_shutdown(void) {
7540 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7541 char date
[FORMAT_TIMESTAMP_MAX
];
7546 (void) logind_set_wall_message();
7548 r
= acquire_bus(BUS_FULL
, &bus
);
7552 switch (arg_action
) {
7556 case ACTION_POWEROFF
:
7557 action
= "poweroff";
7572 action
= strjoina("dry-", action
);
7574 r
= sd_bus_call_method(
7576 "org.freedesktop.login1",
7577 "/org/freedesktop/login1",
7578 "org.freedesktop.login1.Manager",
7586 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7588 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7591 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7596 static int halt_main(void) {
7599 r
= logind_check_inhibitors(arg_action
);
7604 return logind_schedule_shutdown();
7606 if (geteuid() != 0) {
7607 if (arg_dry
|| arg_force
> 0) {
7608 log_error("Must be root.");
7612 /* Try logind if we are a normal user and no special
7613 * mode applies. Maybe PolicyKit allows us to shutdown
7615 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7616 r
= logind_reboot(arg_action
);
7619 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7620 /* requested operation is not
7621 * supported on the local system or
7622 * already in progress */
7624 /* on all other errors, try low-level operation */
7628 if (!arg_dry
&& !arg_force
)
7629 return start_with_fallback();
7631 assert(geteuid() == 0);
7634 if (sd_booted() > 0)
7635 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7637 r
= utmp_put_shutdown();
7639 log_warning_errno(r
, "Failed to write utmp record: %m");
7646 r
= halt_now(arg_action
);
7647 return log_error_errno(r
, "Failed to reboot: %m");
7650 static int runlevel_main(void) {
7651 int r
, runlevel
, previous
;
7653 r
= utmp_get_runlevel(&runlevel
, &previous
);
7660 previous
<= 0 ? 'N' : previous
,
7661 runlevel
<= 0 ? 'N' : runlevel
);
7666 static int logind_cancel_shutdown(void) {
7668 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7672 r
= acquire_bus(BUS_FULL
, &bus
);
7676 (void) logind_set_wall_message();
7678 r
= sd_bus_call_method(
7680 "org.freedesktop.login1",
7681 "/org/freedesktop/login1",
7682 "org.freedesktop.login1.Manager",
7683 "CancelScheduledShutdown",
7687 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7691 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7696 int main(int argc
, char*argv
[]) {
7699 setlocale(LC_ALL
, "");
7700 log_parse_environment();
7703 /* Explicitly not on_tty() to avoid setting cached value.
7704 * This becomes relevant for piping output which might be
7706 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7708 r
= parse_argv(argc
, argv
);
7712 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7713 log_info("Running in chroot, ignoring request.");
7718 /* systemctl_main() will print an error message for the bus
7719 * connection, but only if it needs to */
7721 switch (arg_action
) {
7723 case ACTION_SYSTEMCTL
:
7724 r
= systemctl_main(argc
, argv
);
7728 case ACTION_POWEROFF
:
7734 case ACTION_RUNLEVEL2
:
7735 case ACTION_RUNLEVEL3
:
7736 case ACTION_RUNLEVEL4
:
7737 case ACTION_RUNLEVEL5
:
7739 case ACTION_EMERGENCY
:
7740 case ACTION_DEFAULT
:
7741 r
= start_with_fallback();
7746 r
= reload_with_fallback();
7749 case ACTION_CANCEL_SHUTDOWN
:
7750 r
= logind_cancel_shutdown();
7753 case ACTION_RUNLEVEL
:
7754 r
= runlevel_main();
7757 case _ACTION_INVALID
:
7759 assert_not_reached("Unknown action");
7764 ask_password_agent_close();
7765 polkit_agent_close();
7767 strv_free(arg_types
);
7768 strv_free(arg_states
);
7769 strv_free(arg_properties
);
7771 strv_free(arg_wall
);
7776 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7778 return r
< 0 ? EXIT_FAILURE
: r
;