2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Marc-Antoine Perennou
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/reboot.h>
30 #include <sys/reboot.h>
31 #include <sys/socket.h>
35 #include "sd-daemon.h"
38 #include "alloc-util.h"
39 #include "bus-common-errors.h"
40 #include "bus-error.h"
41 #include "bus-message.h"
43 #include "cgroup-show.h"
44 #include "cgroup-util.h"
49 #include "exit-status.h"
52 #include "formats-util.h"
54 #include "glob-util.h"
55 #include "hostname-util.h"
60 #include "locale-util.h"
62 #include "logs-show.h"
66 #include "parse-util.h"
67 #include "path-lookup.h"
68 #include "path-util.h"
69 #include "process-util.h"
70 #include "rlimit-util.h"
72 #include "signal-util.h"
73 #include "socket-util.h"
74 #include "spawn-ask-password-agent.h"
75 #include "spawn-polkit-agent.h"
77 #include "stat-util.h"
79 #include "terminal-util.h"
80 #include "unit-name.h"
81 #include "user-util.h"
83 #include "utmp-wtmp.h"
87 static char **arg_types
= NULL
;
88 static char **arg_states
= NULL
;
89 static char **arg_properties
= NULL
;
90 static bool arg_all
= false;
91 static enum dependency
{
97 } arg_dependency
= DEPENDENCY_FORWARD
;
98 static const char *arg_job_mode
= "replace";
99 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
100 static bool arg_no_block
= false;
101 static bool arg_no_legend
= false;
102 static bool arg_no_pager
= false;
103 static bool arg_no_wtmp
= false;
104 static bool arg_no_wall
= false;
105 static bool arg_no_reload
= false;
106 static bool arg_show_types
= false;
107 static bool arg_ignore_inhibitors
= false;
108 static bool arg_dry
= false;
109 static bool arg_quiet
= false;
110 static bool arg_full
= false;
111 static bool arg_recursive
= false;
112 static int arg_force
= 0;
113 static bool arg_ask_password
= false;
114 static bool arg_runtime
= false;
115 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
116 static char **arg_wall
= NULL
;
117 static const char *arg_kill_who
= NULL
;
118 static int arg_signal
= SIGTERM
;
119 static char *arg_root
= NULL
;
120 static usec_t arg_when
= 0;
142 ACTION_CANCEL_SHUTDOWN
,
144 } arg_action
= ACTION_SYSTEMCTL
;
145 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
146 static const char *arg_host
= NULL
;
147 static unsigned arg_lines
= 10;
148 static OutputMode arg_output
= OUTPUT_SHORT
;
149 static bool arg_plain
= false;
150 static bool arg_firmware_setup
= false;
151 static bool arg_now
= false;
153 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
154 static int halt_now(enum action a
);
155 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
157 static bool original_stdout_is_tty
;
159 typedef enum BusFocus
{
160 BUS_FULL
, /* The full bus indicated via --system or --user */
161 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
165 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
167 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
170 assert(focus
< _BUS_FOCUS_MAX
);
173 /* We only go directly to the manager, if we are using a local transport */
174 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
177 if (!busses
[focus
]) {
180 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
182 if (focus
== BUS_MANAGER
)
183 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
185 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
187 return log_error_errno(r
, "Failed to connect to bus: %m");
189 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
192 *ret
= busses
[focus
];
196 static void release_busses(void) {
199 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
200 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
203 static void ask_password_agent_open_if_enabled(void) {
205 /* Open the password agent as a child process if necessary */
207 if (!arg_ask_password
)
210 if (arg_scope
!= UNIT_FILE_SYSTEM
)
213 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
216 ask_password_agent_open();
219 static void polkit_agent_open_if_enabled(void) {
221 /* Open the polkit agent as a child process if necessary */
223 if (!arg_ask_password
)
226 if (arg_scope
!= UNIT_FILE_SYSTEM
)
229 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
235 static OutputFlags
get_output_flags(void) {
237 arg_all
* OUTPUT_SHOW_ALL
|
238 arg_full
* OUTPUT_FULL_WIDTH
|
239 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
240 colors_enabled() * OUTPUT_COLOR
|
241 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
244 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
247 if (!sd_bus_error_is_set(error
))
250 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
251 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
252 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
253 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
254 return EXIT_NOPERMISSION
;
256 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
257 return EXIT_NOTINSTALLED
;
259 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
260 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
261 return EXIT_NOTIMPLEMENTED
;
263 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
264 return EXIT_NOTCONFIGURED
;
272 static bool install_client_side(void) {
274 /* Decides when to execute enable/disable/... operations
275 * client-side rather than server-side. */
277 if (running_in_chroot() > 0)
280 if (sd_booted() <= 0)
283 if (!isempty(arg_root
))
286 if (arg_scope
== UNIT_FILE_GLOBAL
)
289 /* Unsupported environment variable, mostly for debugging purposes */
290 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
296 static int compare_unit_info(const void *a
, const void *b
) {
297 const UnitInfo
*u
= a
, *v
= b
;
301 /* First, order by machine */
302 if (!u
->machine
&& v
->machine
)
304 if (u
->machine
&& !v
->machine
)
306 if (u
->machine
&& v
->machine
) {
307 r
= strcasecmp(u
->machine
, v
->machine
);
312 /* Second, order by unit type */
313 d1
= strrchr(u
->id
, '.');
314 d2
= strrchr(v
->id
, '.');
316 r
= strcasecmp(d1
, d2
);
321 /* Third, order by name */
322 return strcasecmp(u
->id
, v
->id
);
325 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
326 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
332 dot
= strrchr(u
->id
, '.');
336 if (!strv_find(arg_types
, dot
+1))
343 if (!strv_isempty(arg_states
))
346 /* By default show all units except the ones in inactive
347 * state and with no pending job */
351 if (streq(u
->active_state
, "inactive") || u
->following
[0])
357 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
358 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
360 unsigned n_shown
= 0;
363 max_id_len
= strlen("UNIT");
364 load_len
= strlen("LOAD");
365 active_len
= strlen("ACTIVE");
366 sub_len
= strlen("SUB");
367 job_len
= strlen("JOB");
370 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
371 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
372 load_len
= MAX(load_len
, strlen(u
->load_state
));
373 active_len
= MAX(active_len
, strlen(u
->active_state
));
374 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
376 if (u
->job_id
!= 0) {
377 job_len
= MAX(job_len
, strlen(u
->job_type
));
381 if (!arg_no_legend
&&
382 (streq(u
->active_state
, "failed") ||
383 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
387 if (!arg_full
&& original_stdout_is_tty
) {
390 id_len
= MIN(max_id_len
, 25u);
391 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
394 basic_len
+= job_len
+ 1;
396 if (basic_len
< (unsigned) columns()) {
397 unsigned extra_len
, incr
;
398 extra_len
= columns() - basic_len
;
400 /* Either UNIT already got 25, or is fully satisfied.
401 * Grant up to 25 to DESC now. */
402 incr
= MIN(extra_len
, 25u);
406 /* split the remaining space between UNIT and DESC,
407 * but do not give UNIT more than it needs. */
409 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
411 desc_len
+= extra_len
- incr
;
417 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
418 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
419 const char *on_loaded
= "", *off_loaded
= "";
420 const char *on_active
= "", *off_active
= "";
421 const char *on_circle
= "", *off_circle
= "";
425 if (!n_shown
&& !arg_no_legend
) {
430 printf("%-*s %-*s %-*s %-*s ",
433 active_len
, "ACTIVE",
437 printf("%-*s ", job_len
, "JOB");
439 if (!arg_full
&& arg_no_pager
)
440 printf("%.*s\n", desc_len
, "DESCRIPTION");
442 printf("%s\n", "DESCRIPTION");
447 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
448 on_loaded
= ansi_highlight_red();
449 on_circle
= ansi_highlight_yellow();
450 off_loaded
= off_circle
= ansi_normal();
452 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
453 on_circle
= on_active
= ansi_highlight_red();
454 off_circle
= off_active
= ansi_normal();
459 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
468 e
= ellipsize(id
, id_len
, 33);
476 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
478 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
479 on_active
, id_len
, id
, off_active
,
480 on_loaded
, load_len
, u
->load_state
, off_loaded
,
481 on_active
, active_len
, u
->active_state
,
482 sub_len
, u
->sub_state
, off_active
,
483 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
486 printf("%.*s\n", desc_len
, u
->description
);
488 printf("%s\n", u
->description
);
491 if (!arg_no_legend
) {
492 const char *on
, *off
;
496 "LOAD = Reflects whether the unit definition was properly loaded.\n"
497 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
498 "SUB = The low-level unit activation state, values depend on unit type.");
499 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
500 on
= ansi_highlight();
503 on
= ansi_highlight_red();
508 printf("%s%u loaded units listed.%s\n"
509 "To show all installed unit files use 'systemctl list-unit-files'.\n",
512 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
513 "To show all installed unit files use 'systemctl list-unit-files'.\n",
520 static int get_unit_list(
524 UnitInfo
**unit_infos
,
526 sd_bus_message
**_reply
) {
528 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
529 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
530 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
539 r
= sd_bus_message_new_method_call(
542 "org.freedesktop.systemd1",
543 "/org/freedesktop/systemd1",
544 "org.freedesktop.systemd1.Manager",
545 "ListUnitsFiltered");
548 return bus_log_create_error(r
);
550 r
= sd_bus_message_append_strv(m
, arg_states
);
552 return bus_log_create_error(r
);
554 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
556 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
558 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
560 return bus_log_parse_error(r
);
562 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
565 if (!output_show_unit(&u
, patterns
))
568 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
571 (*unit_infos
)[c
++] = u
;
574 return bus_log_parse_error(r
);
576 r
= sd_bus_message_exit_container(reply
);
578 return bus_log_parse_error(r
);
586 static void message_set_freep(Set
**set
) {
589 while ((m
= set_steal_first(*set
)))
590 sd_bus_message_unref(m
);
595 static int get_unit_list_recursive(
598 UnitInfo
**_unit_infos
,
602 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
603 _cleanup_(message_set_freep
) Set
*replies
;
604 sd_bus_message
*reply
;
612 replies
= set_new(NULL
);
616 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
620 r
= set_put(replies
, reply
);
622 sd_bus_message_unref(reply
);
627 _cleanup_strv_free_
char **machines
= NULL
;
630 r
= sd_get_machine_names(&machines
);
632 return log_error_errno(r
, "Failed to get machine names: %m");
634 STRV_FOREACH(i
, machines
) {
635 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
638 r
= sd_bus_open_system_machine(&container
, *i
);
640 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
644 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
650 r
= set_put(replies
, reply
);
652 sd_bus_message_unref(reply
);
657 *_machines
= machines
;
662 *_unit_infos
= unit_infos
;
671 static int list_units(int argc
, char *argv
[], void *userdata
) {
672 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
673 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
674 _cleanup_strv_free_
char **machines
= NULL
;
678 pager_open(arg_no_pager
, false);
680 r
= acquire_bus(BUS_MANAGER
, &bus
);
684 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
688 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
689 return output_units_list(unit_infos
, r
);
692 static int get_triggered_units(
697 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
704 r
= sd_bus_get_property_strv(
706 "org.freedesktop.systemd1",
708 "org.freedesktop.systemd1.Unit",
713 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
718 static int get_listening(
720 const char* unit_path
,
723 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
724 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
725 const char *type
, *path
;
728 r
= sd_bus_get_property(
730 "org.freedesktop.systemd1",
732 "org.freedesktop.systemd1.Socket",
738 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
740 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
742 return bus_log_parse_error(r
);
744 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
746 r
= strv_extend(listening
, type
);
750 r
= strv_extend(listening
, path
);
757 return bus_log_parse_error(r
);
759 r
= sd_bus_message_exit_container(reply
);
761 return bus_log_parse_error(r
);
773 /* Note: triggered is a list here, although it almost certainly
774 * will always be one unit. Nevertheless, dbus API allows for multiple
775 * values, so let's follow that. */
778 /* The strv above is shared. free is set only in the first one. */
782 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
788 if (!a
->machine
&& b
->machine
)
790 if (a
->machine
&& !b
->machine
)
792 if (a
->machine
&& b
->machine
) {
793 o
= strcasecmp(a
->machine
, b
->machine
);
798 o
= strcmp(a
->path
, b
->path
);
800 o
= strcmp(a
->type
, b
->type
);
805 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
806 struct socket_info
*s
;
807 unsigned pathlen
= strlen("LISTEN"),
808 typelen
= strlen("TYPE") * arg_show_types
,
809 socklen
= strlen("UNIT"),
810 servlen
= strlen("ACTIVATES");
811 const char *on
, *off
;
813 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
817 socklen
= MAX(socklen
, strlen(s
->id
));
819 typelen
= MAX(typelen
, strlen(s
->type
));
820 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
822 STRV_FOREACH(a
, s
->triggered
)
823 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
824 servlen
= MAX(servlen
, tmp
);
829 printf("%-*s %-*.*s%-*s %s\n",
831 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
835 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
836 _cleanup_free_
char *j
= NULL
;
841 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
849 printf("%-*s %-*s %-*s",
850 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
853 pathlen
, path
, socklen
, s
->id
);
854 STRV_FOREACH(a
, s
->triggered
)
856 a
== s
->triggered
? "" : ",", *a
);
860 on
= ansi_highlight();
865 on
= ansi_highlight_red();
869 if (!arg_no_legend
) {
870 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
872 printf("Pass --all to see loaded but inactive sockets, too.\n");
878 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
879 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
880 _cleanup_strv_free_
char **machines
= NULL
;
881 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
882 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
884 struct socket_info
*s
;
890 pager_open(arg_no_pager
, false);
892 r
= acquire_bus(BUS_MANAGER
, &bus
);
896 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
900 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
901 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
904 if (!endswith(u
->id
, ".socket"))
907 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
911 c
= get_listening(bus
, u
->unit_path
, &listening
);
917 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
922 for (i
= 0; i
< c
; i
++)
923 socket_infos
[cs
+ i
] = (struct socket_info
) {
924 .machine
= u
->machine
,
926 .type
= listening
[i
*2],
927 .path
= listening
[i
*2 + 1],
928 .triggered
= triggered
,
929 .own_triggered
= i
==0,
932 /* from this point on we will cleanup those socket_infos */
935 listening
= triggered
= NULL
; /* avoid cleanup */
938 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
939 (__compar_fn_t
) socket_info_compare
);
941 output_sockets_list(socket_infos
, cs
);
944 assert(cs
== 0 || socket_infos
);
945 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
948 if (s
->own_triggered
)
949 strv_free(s
->triggered
);
955 static int get_next_elapse(
958 dual_timestamp
*next
) {
960 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
968 r
= sd_bus_get_property_trivial(
970 "org.freedesktop.systemd1",
972 "org.freedesktop.systemd1.Timer",
973 "NextElapseUSecMonotonic",
978 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
980 r
= sd_bus_get_property_trivial(
982 "org.freedesktop.systemd1",
984 "org.freedesktop.systemd1.Timer",
985 "NextElapseUSecRealtime",
990 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
996 static int get_last_trigger(
1001 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1008 r
= sd_bus_get_property_trivial(
1010 "org.freedesktop.systemd1",
1012 "org.freedesktop.systemd1.Timer",
1018 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1024 const char* machine
;
1027 usec_t last_trigger
;
1031 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1037 if (!a
->machine
&& b
->machine
)
1039 if (a
->machine
&& !b
->machine
)
1041 if (a
->machine
&& b
->machine
) {
1042 o
= strcasecmp(a
->machine
, b
->machine
);
1047 if (a
->next_elapse
< b
->next_elapse
)
1049 if (a
->next_elapse
> b
->next_elapse
)
1052 return strcmp(a
->id
, b
->id
);
1055 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1056 struct timer_info
*t
;
1058 nextlen
= strlen("NEXT"),
1059 leftlen
= strlen("LEFT"),
1060 lastlen
= strlen("LAST"),
1061 passedlen
= strlen("PASSED"),
1062 unitlen
= strlen("UNIT"),
1063 activatelen
= strlen("ACTIVATES");
1065 const char *on
, *off
;
1067 assert(timer_infos
|| n
== 0);
1069 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1073 if (t
->next_elapse
> 0) {
1074 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1076 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1077 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1079 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1080 leftlen
= MAX(leftlen
, strlen(trel
));
1083 if (t
->last_trigger
> 0) {
1084 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1086 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1087 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1089 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1090 passedlen
= MAX(passedlen
, strlen(trel
));
1093 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1095 STRV_FOREACH(a
, t
->triggered
)
1096 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1098 activatelen
= MAX(activatelen
, ul
);
1103 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1107 passedlen
, "PASSED",
1111 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1112 _cleanup_free_
char *j
= NULL
;
1114 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1115 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1118 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1119 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1121 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1122 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1125 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1132 printf("%-*s %-*s %-*s %-*s %-*s",
1133 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1135 STRV_FOREACH(a
, t
->triggered
)
1137 a
== t
->triggered
? "" : ",", *a
);
1141 on
= ansi_highlight();
1142 off
= ansi_normal();
1146 on
= ansi_highlight_red();
1147 off
= ansi_normal();
1150 if (!arg_no_legend
) {
1151 printf("%s%u timers listed.%s\n", on
, n
, off
);
1153 printf("Pass --all to see loaded but inactive timers, too.\n");
1159 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1165 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1168 if (next
->monotonic
> nw
->monotonic
)
1169 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1171 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1173 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1174 next_elapse
= MIN(converted
, next
->realtime
);
1176 next_elapse
= converted
;
1179 next_elapse
= next
->realtime
;
1184 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1185 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1186 _cleanup_strv_free_
char **machines
= NULL
;
1187 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1188 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1189 struct timer_info
*t
;
1197 pager_open(arg_no_pager
, false);
1199 r
= acquire_bus(BUS_MANAGER
, &bus
);
1203 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1207 dual_timestamp_get(&nw
);
1209 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1210 _cleanup_strv_free_
char **triggered
= NULL
;
1211 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1214 if (!endswith(u
->id
, ".timer"))
1217 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1221 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1225 get_last_trigger(bus
, u
->unit_path
, &last
);
1227 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1232 m
= calc_next_elapse(&nw
, &next
);
1234 timer_infos
[c
++] = (struct timer_info
) {
1235 .machine
= u
->machine
,
1238 .last_trigger
= last
,
1239 .triggered
= triggered
,
1242 triggered
= NULL
; /* avoid cleanup */
1245 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1246 (__compar_fn_t
) timer_info_compare
);
1248 output_timers_list(timer_infos
, c
);
1251 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1252 strv_free(t
->triggered
);
1257 static int compare_unit_file_list(const void *a
, const void *b
) {
1258 const char *d1
, *d2
;
1259 const UnitFileList
*u
= a
, *v
= b
;
1261 d1
= strrchr(u
->path
, '.');
1262 d2
= strrchr(v
->path
, '.');
1267 r
= strcasecmp(d1
, d2
);
1272 return strcasecmp(basename(u
->path
), basename(v
->path
));
1275 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1276 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1279 if (!strv_isempty(arg_types
)) {
1282 dot
= strrchr(u
->path
, '.');
1286 if (!strv_find(arg_types
, dot
+1))
1290 if (!strv_isempty(arg_states
) &&
1291 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1297 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1298 unsigned max_id_len
, id_cols
, state_cols
;
1299 const UnitFileList
*u
;
1301 max_id_len
= strlen("UNIT FILE");
1302 state_cols
= strlen("STATE");
1304 for (u
= units
; u
< units
+ c
; u
++) {
1305 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1306 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1310 unsigned basic_cols
;
1312 id_cols
= MIN(max_id_len
, 25u);
1313 basic_cols
= 1 + id_cols
+ state_cols
;
1314 if (basic_cols
< (unsigned) columns())
1315 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1317 id_cols
= max_id_len
;
1320 printf("%-*s %-*s\n",
1321 id_cols
, "UNIT FILE",
1322 state_cols
, "STATE");
1324 for (u
= units
; u
< units
+ c
; u
++) {
1325 _cleanup_free_
char *e
= NULL
;
1326 const char *on
, *off
;
1329 if (IN_SET(u
->state
,
1331 UNIT_FILE_MASKED_RUNTIME
,
1334 on
= ansi_highlight_red();
1335 off
= ansi_normal();
1336 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1337 on
= ansi_highlight_green();
1338 off
= ansi_normal();
1342 id
= basename(u
->path
);
1344 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1346 printf("%-*s %s%-*s%s\n",
1347 id_cols
, e
? e
: id
,
1348 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1352 printf("\n%u unit files listed.\n", c
);
1355 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1356 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1357 _cleanup_free_ UnitFileList
*units
= NULL
;
1365 pager_open(arg_no_pager
, false);
1367 if (install_client_side()) {
1373 h
= hashmap_new(&string_hash_ops
);
1377 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1379 unit_file_list_free(h
);
1380 return log_error_errno(r
, "Failed to get unit file list: %m");
1383 n_units
= hashmap_size(h
);
1385 units
= new(UnitFileList
, n_units
);
1386 if (!units
&& n_units
> 0) {
1387 unit_file_list_free(h
);
1391 HASHMAP_FOREACH(u
, h
, i
) {
1392 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1399 assert(c
<= n_units
);
1402 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1405 r
= acquire_bus(BUS_MANAGER
, &bus
);
1409 r
= sd_bus_call_method(
1411 "org.freedesktop.systemd1",
1412 "/org/freedesktop/systemd1",
1413 "org.freedesktop.systemd1.Manager",
1419 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1421 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1423 return bus_log_parse_error(r
);
1425 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1427 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1430 units
[c
] = (struct UnitFileList
) {
1432 unit_file_state_from_string(state
)
1435 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1440 return bus_log_parse_error(r
);
1442 r
= sd_bus_message_exit_container(reply
);
1444 return bus_log_parse_error(r
);
1447 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1448 output_unit_file_list(units
, c
);
1450 if (install_client_side()) {
1451 for (unit
= units
; unit
< units
+ c
; unit
++)
1458 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1459 _cleanup_free_
char *n
= NULL
;
1460 size_t max_len
= MAX(columns(),20u);
1466 for (i
= level
- 1; i
>= 0; i
--) {
1468 if (len
> max_len
- 3 && !arg_full
) {
1469 printf("%s...\n",max_len
% 2 ? "" : " ");
1472 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1476 if (len
> max_len
- 3 && !arg_full
) {
1477 printf("%s...\n",max_len
% 2 ? "" : " ");
1481 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1485 printf("%s\n", name
);
1489 n
= ellipsize(name
, max_len
-len
, 100);
1497 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1499 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1500 [DEPENDENCY_FORWARD
] = "Requires\0"
1505 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1510 [DEPENDENCY_AFTER
] = "After\0",
1511 [DEPENDENCY_BEFORE
] = "Before\0",
1514 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1515 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1516 _cleanup_strv_free_
char **ret
= NULL
;
1517 _cleanup_free_
char *path
= NULL
;
1523 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1525 path
= unit_dbus_path_from_name(name
);
1529 r
= sd_bus_call_method(
1531 "org.freedesktop.systemd1",
1533 "org.freedesktop.DBus.Properties",
1537 "s", "org.freedesktop.systemd1.Unit");
1539 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1541 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1543 return bus_log_parse_error(r
);
1545 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1548 r
= sd_bus_message_read(reply
, "s", &prop
);
1550 return bus_log_parse_error(r
);
1552 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1553 r
= sd_bus_message_skip(reply
, "v");
1555 return bus_log_parse_error(r
);
1558 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1560 return bus_log_parse_error(r
);
1562 r
= bus_message_read_strv_extend(reply
, &ret
);
1564 return bus_log_parse_error(r
);
1566 r
= sd_bus_message_exit_container(reply
);
1568 return bus_log_parse_error(r
);
1571 r
= sd_bus_message_exit_container(reply
);
1573 return bus_log_parse_error(r
);
1577 return bus_log_parse_error(r
);
1579 r
= sd_bus_message_exit_container(reply
);
1581 return bus_log_parse_error(r
);
1589 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1590 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1592 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1594 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1597 return strcasecmp(*a
, *b
);
1600 static int list_dependencies_one(
1605 unsigned int branches
) {
1607 _cleanup_strv_free_
char **deps
= NULL
;
1615 r
= strv_extend(units
, name
);
1619 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1623 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1625 STRV_FOREACH(c
, deps
) {
1626 if (strv_contains(*units
, *c
)) {
1628 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1638 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1641 (void) get_state_one_unit(bus
, *c
, &active_state
);
1642 switch (active_state
) {
1644 case UNIT_RELOADING
:
1645 case UNIT_ACTIVATING
:
1646 on
= ansi_highlight_green();
1650 case UNIT_DEACTIVATING
:
1655 on
= ansi_highlight_red();
1659 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1662 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1666 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1667 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1674 strv_remove(*units
, name
);
1679 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1680 _cleanup_strv_free_
char **units
= NULL
;
1681 _cleanup_free_
char *unit
= NULL
;
1687 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1689 return log_error_errno(r
, "Failed to mangle unit name: %m");
1693 u
= SPECIAL_DEFAULT_TARGET
;
1695 pager_open(arg_no_pager
, false);
1697 r
= acquire_bus(BUS_MANAGER
, &bus
);
1703 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1706 struct machine_info
{
1710 char *control_group
;
1711 uint32_t n_failed_units
;
1716 static const struct bus_properties_map machine_info_property_map
[] = {
1717 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1718 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1719 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1720 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1721 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1725 static void machine_info_clear(struct machine_info
*info
) {
1729 free(info
->control_group
);
1734 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1740 for (i
= 0; i
< n
; i
++)
1741 machine_info_clear(&machine_infos
[i
]);
1743 free(machine_infos
);
1746 static int compare_machine_info(const void *a
, const void *b
) {
1747 const struct machine_info
*u
= a
, *v
= b
;
1749 if (u
->is_host
!= v
->is_host
)
1750 return u
->is_host
> v
->is_host
? -1 : 1;
1752 return strcasecmp(u
->name
, v
->name
);
1755 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1756 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1762 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1769 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1776 static bool output_show_machine(const char *name
, char **patterns
) {
1777 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1780 static int get_machine_list(
1782 struct machine_info
**_machine_infos
,
1785 struct machine_info
*machine_infos
= NULL
;
1786 _cleanup_strv_free_
char **m
= NULL
;
1787 _cleanup_free_
char *hn
= NULL
;
1792 hn
= gethostname_malloc();
1796 if (output_show_machine(hn
, patterns
)) {
1797 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1800 machine_infos
[c
].is_host
= true;
1801 machine_infos
[c
].name
= hn
;
1804 get_machine_properties(bus
, &machine_infos
[c
]);
1808 r
= sd_get_machine_names(&m
);
1810 return log_error_errno(r
, "Failed to get machine list: %m");
1812 STRV_FOREACH(i
, m
) {
1813 _cleanup_free_
char *class = NULL
;
1815 if (!output_show_machine(*i
, patterns
))
1818 sd_machine_get_class(*i
, &class);
1819 if (!streq_ptr(class, "container"))
1822 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1823 free_machines_list(machine_infos
, c
);
1827 machine_infos
[c
].is_host
= false;
1828 machine_infos
[c
].name
= strdup(*i
);
1829 if (!machine_infos
[c
].name
) {
1830 free_machines_list(machine_infos
, c
);
1834 get_machine_properties(NULL
, &machine_infos
[c
]);
1838 *_machine_infos
= machine_infos
;
1842 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1843 struct machine_info
*m
;
1846 namelen
= sizeof("NAME") - 1,
1847 statelen
= sizeof("STATE") - 1,
1848 failedlen
= sizeof("FAILED") - 1,
1849 jobslen
= sizeof("JOBS") - 1;
1851 assert(machine_infos
|| n
== 0);
1853 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1854 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1855 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1856 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1857 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1859 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1863 if (!arg_no_legend
) {
1867 printf("%-*s %-*s %-*s %-*s\n",
1870 failedlen
, "FAILED",
1874 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1875 const char *on_state
= "", *off_state
= "";
1876 const char *on_failed
= "", *off_failed
= "";
1877 bool circle
= false;
1879 if (streq_ptr(m
->state
, "degraded")) {
1880 on_state
= ansi_highlight_red();
1881 off_state
= ansi_normal();
1883 } else if (!streq_ptr(m
->state
, "running")) {
1884 on_state
= ansi_highlight_yellow();
1885 off_state
= ansi_normal();
1889 if (m
->n_failed_units
> 0) {
1890 on_failed
= ansi_highlight_red();
1891 off_failed
= ansi_normal();
1893 on_failed
= off_failed
= "";
1896 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1899 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1900 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1901 on_state
, statelen
, strna(m
->state
), off_state
,
1902 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1903 jobslen
, m
->n_jobs
);
1905 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1906 namelen
, strna(m
->name
),
1907 on_state
, statelen
, strna(m
->state
), off_state
,
1908 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1909 jobslen
, m
->n_jobs
);
1913 printf("\n%u machines listed.\n", n
);
1916 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1917 struct machine_info
*machine_infos
= NULL
;
1921 if (geteuid() != 0) {
1922 log_error("Must be root.");
1926 pager_open(arg_no_pager
, false);
1928 r
= acquire_bus(BUS_MANAGER
, &bus
);
1932 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1936 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1937 output_machines_list(machine_infos
, r
);
1938 free_machines_list(machine_infos
, r
);
1943 static int get_default(int argc
, char *argv
[], void *userdata
) {
1944 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1945 _cleanup_free_
char *_path
= NULL
;
1949 if (install_client_side()) {
1950 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1952 return log_error_errno(r
, "Failed to get default target: %m");
1956 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1959 r
= acquire_bus(BUS_MANAGER
, &bus
);
1963 r
= sd_bus_call_method(
1965 "org.freedesktop.systemd1",
1966 "/org/freedesktop/systemd1",
1967 "org.freedesktop.systemd1.Manager",
1973 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1975 r
= sd_bus_message_read(reply
, "s", &path
);
1977 return bus_log_parse_error(r
);
1981 printf("%s\n", path
);
1986 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1989 assert(changes
|| n_changes
== 0);
1991 for (i
= 0; i
< n_changes
; i
++) {
1992 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1993 log_info("Created symlink %s, pointing to %s.", changes
[i
].path
, changes
[i
].source
);
1995 log_info("Removed symlink %s.", changes
[i
].path
);
1999 static int set_default(int argc
, char *argv
[], void *userdata
) {
2000 _cleanup_free_
char *unit
= NULL
;
2006 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2008 return log_error_errno(r
, "Failed to mangle unit name: %m");
2010 if (install_client_side()) {
2011 UnitFileChange
*changes
= NULL
;
2012 unsigned n_changes
= 0;
2014 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2016 return log_error_errno(r
, "Failed to set default target: %m");
2019 dump_unit_file_changes(changes
, n_changes
);
2021 unit_file_changes_free(changes
, n_changes
);
2024 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2025 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2028 polkit_agent_open_if_enabled();
2030 r
= acquire_bus(BUS_MANAGER
, &bus
);
2034 r
= sd_bus_call_method(
2036 "org.freedesktop.systemd1",
2037 "/org/freedesktop/systemd1",
2038 "org.freedesktop.systemd1.Manager",
2044 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2046 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2050 /* Try to reload if enabled */
2052 r
= daemon_reload(argc
, argv
, userdata
);
2062 const char *name
, *type
, *state
;
2065 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2066 unsigned id_len
, unit_len
, type_len
, state_len
;
2067 const struct job_info
*j
;
2068 const char *on
, *off
;
2069 bool shorten
= false;
2071 assert(n
== 0 || jobs
);
2074 if (!arg_no_legend
) {
2075 on
= ansi_highlight_green();
2076 off
= ansi_normal();
2078 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2083 pager_open(arg_no_pager
, false);
2085 id_len
= strlen("JOB");
2086 unit_len
= strlen("UNIT");
2087 type_len
= strlen("TYPE");
2088 state_len
= strlen("STATE");
2090 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2091 uint32_t id
= j
->id
;
2092 assert(j
->name
&& j
->type
&& j
->state
);
2094 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2095 unit_len
= MAX(unit_len
, strlen(j
->name
));
2096 type_len
= MAX(type_len
, strlen(j
->type
));
2097 state_len
= MAX(state_len
, strlen(j
->state
));
2100 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2101 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2106 printf("%*s %-*s %-*s %-*s\n",
2110 state_len
, "STATE");
2112 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2113 _cleanup_free_
char *e
= NULL
;
2115 if (streq(j
->state
, "running")) {
2116 on
= ansi_highlight();
2117 off
= ansi_normal();
2121 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2122 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2124 on
, unit_len
, e
? e
: j
->name
, off
,
2126 on
, state_len
, j
->state
, off
);
2129 if (!arg_no_legend
) {
2130 on
= ansi_highlight();
2131 off
= ansi_normal();
2133 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2137 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2138 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2141 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2142 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2143 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2144 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2145 _cleanup_free_
struct job_info
*jobs
= NULL
;
2151 bool skipped
= false;
2153 pager_open(arg_no_pager
, false);
2155 r
= acquire_bus(BUS_MANAGER
, &bus
);
2159 r
= sd_bus_call_method(
2161 "org.freedesktop.systemd1",
2162 "/org/freedesktop/systemd1",
2163 "org.freedesktop.systemd1.Manager",
2169 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2171 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2173 return bus_log_parse_error(r
);
2175 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2176 struct job_info job
= { id
, name
, type
, state
};
2178 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2183 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2189 return bus_log_parse_error(r
);
2191 r
= sd_bus_message_exit_container(reply
);
2193 return bus_log_parse_error(r
);
2195 output_jobs_list(jobs
, c
, skipped
);
2199 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2205 return daemon_reload(argc
, argv
, userdata
);
2207 polkit_agent_open_if_enabled();
2209 r
= acquire_bus(BUS_MANAGER
, &bus
);
2213 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2214 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2218 q
= safe_atou32(*name
, &id
);
2220 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2222 q
= sd_bus_call_method(
2224 "org.freedesktop.systemd1",
2225 "/org/freedesktop/systemd1",
2226 "org.freedesktop.systemd1.Manager",
2232 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2241 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2242 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2246 /* We ignore all errors here, since this is used to show a
2249 /* We don't use unit_dbus_path_from_name() directly since we
2250 * don't want to load the unit if it isn't loaded. */
2252 r
= sd_bus_call_method(
2254 "org.freedesktop.systemd1",
2255 "/org/freedesktop/systemd1",
2256 "org.freedesktop.systemd1.Manager",
2264 r
= sd_bus_message_read(reply
, "o", &path
);
2268 r
= sd_bus_get_property_trivial(
2270 "org.freedesktop.systemd1",
2272 "org.freedesktop.systemd1.Unit",
2282 static void warn_unit_file_changed(const char *name
) {
2283 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2284 ansi_highlight_red(),
2287 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2290 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2297 STRV_FOREACH(p
, lp
->unit_path
) {
2298 _cleanup_free_
char *path
;
2300 path
= path_join(arg_root
, *p
, unit_name
);
2304 if (access(path
, F_OK
) == 0) {
2314 static int unit_find_paths(
2316 const char *unit_name
,
2318 char **fragment_path
,
2319 char ***dropin_paths
) {
2321 _cleanup_free_
char *path
= NULL
;
2322 _cleanup_strv_free_
char **dropins
= NULL
;
2326 * Finds where the unit is defined on disk. Returns 0 if the unit
2327 * is not found. Returns 1 if it is found, and sets
2328 * - the path to the unit in *path, if it exists on disk,
2329 * - and a strv of existing drop-ins in *dropins,
2330 * if the arg is not NULL and any dropins were found.
2334 assert(fragment_path
);
2337 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2338 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2339 _cleanup_free_
char *unit
= NULL
;
2341 unit
= unit_dbus_path_from_name(unit_name
);
2345 r
= sd_bus_get_property_string(
2347 "org.freedesktop.systemd1",
2349 "org.freedesktop.systemd1.Unit",
2354 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2357 r
= sd_bus_get_property_strv(
2359 "org.freedesktop.systemd1",
2361 "org.freedesktop.systemd1.Unit",
2366 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2369 _cleanup_set_free_ Set
*names
;
2371 names
= set_new(NULL
);
2375 r
= set_put(names
, unit_name
);
2377 return log_error_errno(r
, "Failed to add unit name: %m");
2379 r
= unit_file_find_path(lp
, unit_name
, &path
);
2384 _cleanup_free_
char *template = NULL
;
2386 r
= unit_name_template(unit_name
, &template);
2387 if (r
< 0 && r
!= -EINVAL
)
2388 return log_error_errno(r
, "Failed to determine template name: %m");
2390 r
= unit_file_find_path(lp
, template, &path
);
2397 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2405 if (!isempty(path
)) {
2406 *fragment_path
= path
;
2411 if (dropin_paths
&& !strv_isempty(dropins
)) {
2412 *dropin_paths
= dropins
;
2418 log_error("No files found for %s.", unit_name
);
2423 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2424 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2425 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2426 _cleanup_free_
char *buf
= NULL
;
2427 UnitActiveState state
;
2432 assert(active_state
);
2434 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2436 r
= sd_bus_call_method(
2438 "org.freedesktop.systemd1",
2439 "/org/freedesktop/systemd1",
2440 "org.freedesktop.systemd1.Manager",
2446 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2447 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2449 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2450 * considered inactive. */
2451 state
= UNIT_INACTIVE
;
2454 r
= sd_bus_message_read(reply
, "o", &path
);
2456 return bus_log_parse_error(r
);
2458 r
= sd_bus_get_property_string(
2460 "org.freedesktop.systemd1",
2462 "org.freedesktop.systemd1.Unit",
2467 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2469 state
= unit_active_state_from_string(buf
);
2470 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2471 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2476 *active_state
= state
;
2480 static int check_triggering_units(
2484 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2485 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2486 _cleanup_strv_free_
char **triggered_by
= NULL
;
2487 bool print_warning_label
= true;
2488 UnitActiveState active_state
;
2492 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2494 return log_error_errno(r
, "Failed to mangle unit name: %m");
2496 path
= unit_dbus_path_from_name(n
);
2500 r
= sd_bus_get_property_string(
2502 "org.freedesktop.systemd1",
2504 "org.freedesktop.systemd1.Unit",
2509 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2511 if (streq(load_state
, "masked"))
2514 r
= sd_bus_get_property_strv(
2516 "org.freedesktop.systemd1",
2518 "org.freedesktop.systemd1.Unit",
2523 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2525 STRV_FOREACH(i
, triggered_by
) {
2526 r
= get_state_one_unit(bus
, *i
, &active_state
);
2530 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2533 if (print_warning_label
) {
2534 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2535 print_warning_label
= false;
2538 log_warning(" %s", *i
);
2544 static const struct {
2547 } unit_actions
[] = {
2548 { "start", "StartUnit" },
2549 { "stop", "StopUnit" },
2550 { "condstop", "StopUnit" },
2551 { "reload", "ReloadUnit" },
2552 { "restart", "RestartUnit" },
2553 { "try-restart", "TryRestartUnit" },
2554 { "condrestart", "TryRestartUnit" },
2555 { "reload-or-restart", "ReloadOrRestartUnit" },
2556 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2557 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2558 { "condreload", "ReloadOrTryRestartUnit" },
2559 { "force-reload", "ReloadOrTryRestartUnit" }
2562 static const char *verb_to_method(const char *verb
) {
2565 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2566 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2567 return unit_actions
[i
].method
;
2572 static const char *method_to_verb(const char *method
) {
2575 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2576 if (streq_ptr(unit_actions
[i
].method
, method
))
2577 return unit_actions
[i
].verb
;
2582 static int start_unit_one(
2587 sd_bus_error
*error
,
2588 BusWaitForJobs
*w
) {
2590 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2599 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2601 r
= sd_bus_call_method(
2603 "org.freedesktop.systemd1",
2604 "/org/freedesktop/systemd1",
2605 "org.freedesktop.systemd1.Manager",
2613 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2614 /* There's always a fallback possible for
2615 * legacy actions. */
2616 return -EADDRNOTAVAIL
;
2618 verb
= method_to_verb(method
);
2620 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2622 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2623 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2624 log_error("See %s logs and 'systemctl%s status %s' for details.",
2625 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2626 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2632 r
= sd_bus_message_read(reply
, "o", &path
);
2634 return bus_log_parse_error(r
);
2636 if (need_daemon_reload(bus
, name
) > 0)
2637 warn_unit_file_changed(name
);
2640 log_debug("Adding %s to the set", path
);
2641 r
= bus_wait_for_jobs_add(w
, path
);
2649 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2650 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2657 STRV_FOREACH(name
, names
) {
2661 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2663 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2665 return log_error_errno(r
, "Failed to mangle name: %m");
2667 if (string_is_glob(t
))
2668 r
= strv_consume(&globs
, t
);
2670 r
= strv_consume(&mangled
, t
);
2675 /* Query the manager only if any of the names are a glob, since
2676 * this is fairly expensive */
2677 if (!strv_isempty(globs
)) {
2678 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2679 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2680 size_t allocated
, n
;
2682 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2686 n
= strv_length(mangled
);
2689 for (i
= 0; i
< r
; i
++) {
2690 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2693 mangled
[n
] = strdup(unit_infos
[i
].id
);
2697 mangled
[++n
] = NULL
;
2702 mangled
= NULL
; /* do not free */
2707 static const struct {
2711 } action_table
[_ACTION_MAX
] = {
2712 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2713 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2714 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2715 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2716 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2717 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2718 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2719 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2720 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2721 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2722 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2723 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2724 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2725 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2726 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2729 static enum action
verb_to_action(const char *verb
) {
2732 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2733 if (streq_ptr(action_table
[i
].verb
, verb
))
2736 return _ACTION_INVALID
;
2739 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2740 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2741 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2742 _cleanup_strv_free_
char **names
= NULL
;
2747 ask_password_agent_open_if_enabled();
2748 polkit_agent_open_if_enabled();
2750 r
= acquire_bus(BUS_MANAGER
, &bus
);
2754 if (arg_action
== ACTION_SYSTEMCTL
) {
2757 method
= verb_to_method(argv
[0]);
2758 action
= verb_to_action(argv
[0]);
2760 if (streq(argv
[0], "isolate")) {
2764 mode
= action_table
[action
].mode
?: arg_job_mode
;
2766 one_name
= action_table
[action
].target
;
2768 assert(arg_action
< ELEMENTSOF(action_table
));
2769 assert(action_table
[arg_action
].target
);
2771 method
= "StartUnit";
2773 mode
= action_table
[arg_action
].mode
;
2774 one_name
= action_table
[arg_action
].target
;
2778 names
= strv_new(one_name
, NULL
);
2780 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2782 return log_error_errno(r
, "Failed to expand names: %m");
2785 if (!arg_no_block
) {
2786 r
= bus_wait_for_jobs_new(bus
, &w
);
2788 return log_error_errno(r
, "Could not watch jobs: %m");
2791 STRV_FOREACH(name
, names
) {
2792 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2795 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2796 if (r
>= 0 && q
< 0)
2797 r
= translate_bus_error_to_exit_status(q
, &error
);
2800 if (!arg_no_block
) {
2801 int q
, arg_count
= 0;
2802 const char* extra_args
[4] = {};
2804 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2805 extra_args
[arg_count
++] = "--user";
2807 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2808 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2809 extra_args
[arg_count
++] = "-H";
2810 extra_args
[arg_count
++] = arg_host
;
2811 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2812 extra_args
[arg_count
++] = "-M";
2813 extra_args
[arg_count
++] = arg_host
;
2816 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2820 /* When stopping units, warn if they can still be triggered by
2821 * another active unit (socket, path, timer) */
2822 if (!arg_quiet
&& streq(method
, "StopUnit"))
2823 STRV_FOREACH(name
, names
)
2824 check_triggering_units(bus
, *name
);
2830 static int logind_set_wall_message(void) {
2832 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2834 _cleanup_free_
char *m
= NULL
;
2837 r
= acquire_bus(BUS_FULL
, &bus
);
2841 m
= strv_join(arg_wall
, " ");
2845 r
= sd_bus_call_method(
2847 "org.freedesktop.login1",
2848 "/org/freedesktop/login1",
2849 "org.freedesktop.login1.Manager",
2858 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2864 /* Ask systemd-logind, which might grant access to unprivileged users
2865 * through PolicyKit */
2866 static int logind_reboot(enum action a
) {
2868 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2869 const char *method
, *description
;
2873 polkit_agent_open_if_enabled();
2874 (void) logind_set_wall_message();
2876 r
= acquire_bus(BUS_FULL
, &bus
);
2884 description
= "reboot system";
2887 case ACTION_POWEROFF
:
2888 method
= "PowerOff";
2889 description
= "power off system";
2892 case ACTION_SUSPEND
:
2894 description
= "suspend system";
2897 case ACTION_HIBERNATE
:
2898 method
= "Hibernate";
2899 description
= "hibernate system";
2902 case ACTION_HYBRID_SLEEP
:
2903 method
= "HybridSleep";
2904 description
= "put system into hybrid sleep";
2911 r
= sd_bus_call_method(
2913 "org.freedesktop.login1",
2914 "/org/freedesktop/login1",
2915 "org.freedesktop.login1.Manager",
2919 "b", arg_ask_password
);
2921 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2929 static int logind_check_inhibitors(enum action a
) {
2931 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2932 _cleanup_strv_free_
char **sessions
= NULL
;
2933 const char *what
, *who
, *why
, *mode
;
2940 if (arg_ignore_inhibitors
|| arg_force
> 0)
2952 r
= acquire_bus(BUS_FULL
, &bus
);
2956 r
= sd_bus_call_method(
2958 "org.freedesktop.login1",
2959 "/org/freedesktop/login1",
2960 "org.freedesktop.login1.Manager",
2966 /* If logind is not around, then there are no inhibitors... */
2969 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2971 return bus_log_parse_error(r
);
2973 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2974 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2975 _cleanup_strv_free_
char **sv
= NULL
;
2977 if (!streq(mode
, "block"))
2980 sv
= strv_split(what
, ":");
2984 if ((pid_t
) pid
< 0)
2985 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2987 if (!strv_contains(sv
,
2992 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2995 get_process_comm(pid
, &comm
);
2996 user
= uid_to_name(uid
);
2998 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2999 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3004 return bus_log_parse_error(r
);
3006 r
= sd_bus_message_exit_container(reply
);
3008 return bus_log_parse_error(r
);
3010 /* Check for current sessions */
3011 sd_get_sessions(&sessions
);
3012 STRV_FOREACH(s
, sessions
) {
3013 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3015 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3018 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3021 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3024 sd_session_get_tty(*s
, &tty
);
3025 sd_session_get_seat(*s
, &seat
);
3026 sd_session_get_service(*s
, &service
);
3027 user
= uid_to_name(uid
);
3029 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3036 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3037 action_table
[a
].verb
);
3045 static int logind_prepare_firmware_setup(void) {
3047 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3051 r
= acquire_bus(BUS_FULL
, &bus
);
3055 r
= sd_bus_call_method(
3057 "org.freedesktop.login1",
3058 "/org/freedesktop/login1",
3059 "org.freedesktop.login1.Manager",
3060 "SetRebootToFirmwareSetup",
3065 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3069 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3074 static int prepare_firmware_setup(void) {
3077 if (!arg_firmware_setup
)
3080 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3082 r
= efi_set_reboot_to_firmware(true);
3084 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3089 return logind_prepare_firmware_setup();
3092 static int set_exit_code(uint8_t code
) {
3093 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3097 r
= acquire_bus(BUS_MANAGER
, &bus
);
3101 r
= sd_bus_call_method(
3103 "org.freedesktop.systemd1",
3104 "/org/freedesktop/systemd1",
3105 "org.freedesktop.systemd1.Manager",
3111 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3116 static int start_special(int argc
, char *argv
[], void *userdata
) {
3122 a
= verb_to_action(argv
[0]);
3124 r
= logind_check_inhibitors(a
);
3128 if (arg_force
>= 2 && geteuid() != 0) {
3129 log_error("Must be root.");
3133 r
= prepare_firmware_setup();
3137 if (a
== ACTION_REBOOT
&& argc
> 1) {
3138 r
= update_reboot_param_file(argv
[1]);
3142 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3145 /* If the exit code is not given on the command line,
3146 * don't reset it to zero: just keep it as it might
3147 * have been set previously. */
3149 r
= safe_atou8(argv
[1], &code
);
3151 return log_error_errno(r
, "Invalid exit code.");
3153 r
= set_exit_code(code
);
3158 if (arg_force
>= 2 &&
3165 if (arg_force
>= 1 &&
3172 return daemon_reload(argc
, argv
, userdata
);
3174 /* First try logind, to allow authentication with polkit */
3180 ACTION_HYBRID_SLEEP
)) {
3181 r
= logind_reboot(a
);
3184 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3185 /* requested operation is not supported or already in progress */
3188 /* On all other errors, try low-level operation */
3191 return start_unit(argc
, argv
, userdata
);
3194 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3195 _cleanup_strv_free_
char **names
= NULL
;
3196 UnitActiveState active_state
;
3202 r
= acquire_bus(BUS_MANAGER
, &bus
);
3206 r
= expand_names(bus
, args
, NULL
, &names
);
3208 return log_error_errno(r
, "Failed to expand names: %m");
3210 STRV_FOREACH(name
, names
) {
3211 r
= get_state_one_unit(bus
, *name
, &active_state
);
3216 puts(unit_active_state_to_string(active_state
));
3218 for (i
= 0; i
< nb_states
; ++i
)
3219 if (good_states
[i
] == active_state
)
3223 /* use the given return code for the case that we won't find
3224 * any unit which matches the list */
3225 return found
? 0 : code
;
3228 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3229 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3230 /* According to LSB: 3, "program is not running" */
3231 return check_unit_generic(3, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3234 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3235 const UnitActiveState states
[] = { UNIT_FAILED
};
3236 return check_unit_generic(1, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3239 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3240 _cleanup_strv_free_
char **names
= NULL
;
3241 char *kill_who
= NULL
, **name
;
3245 polkit_agent_open_if_enabled();
3247 r
= acquire_bus(BUS_MANAGER
, &bus
);
3252 arg_kill_who
= "all";
3254 /* --fail was specified */
3255 if (streq(arg_job_mode
, "fail"))
3256 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3258 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3260 return log_error_errno(r
, "Failed to expand names: %m");
3262 STRV_FOREACH(name
, names
) {
3263 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3265 q
= sd_bus_call_method(
3267 "org.freedesktop.systemd1",
3268 "/org/freedesktop/systemd1",
3269 "org.freedesktop.systemd1.Manager",
3273 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3275 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3284 typedef struct ExecStatusInfo
{
3292 usec_t start_timestamp
;
3293 usec_t exit_timestamp
;
3298 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3301 static void exec_status_info_free(ExecStatusInfo
*i
) {
3310 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3311 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3314 int32_t code
, status
;
3320 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3322 return bus_log_parse_error(r
);
3326 r
= sd_bus_message_read(m
, "s", &path
);
3328 return bus_log_parse_error(r
);
3330 i
->path
= strdup(path
);
3334 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3336 return bus_log_parse_error(r
);
3338 r
= sd_bus_message_read(m
,
3341 &start_timestamp
, &start_timestamp_monotonic
,
3342 &exit_timestamp
, &exit_timestamp_monotonic
,
3346 return bus_log_parse_error(r
);
3349 i
->start_timestamp
= (usec_t
) start_timestamp
;
3350 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3351 i
->pid
= (pid_t
) pid
;
3355 r
= sd_bus_message_exit_container(m
);
3357 return bus_log_parse_error(r
);
3362 typedef struct UnitStatusInfo
{
3364 const char *load_state
;
3365 const char *active_state
;
3366 const char *sub_state
;
3367 const char *unit_file_state
;
3368 const char *unit_file_preset
;
3370 const char *description
;
3371 const char *following
;
3373 char **documentation
;
3375 const char *fragment_path
;
3376 const char *source_path
;
3377 const char *control_group
;
3379 char **dropin_paths
;
3381 const char *load_error
;
3384 usec_t inactive_exit_timestamp
;
3385 usec_t inactive_exit_timestamp_monotonic
;
3386 usec_t active_enter_timestamp
;
3387 usec_t active_exit_timestamp
;
3388 usec_t inactive_enter_timestamp
;
3390 bool need_daemon_reload
;
3396 const char *status_text
;
3397 const char *pid_file
;
3401 usec_t start_timestamp
;
3402 usec_t exit_timestamp
;
3404 int exit_code
, exit_status
;
3406 usec_t condition_timestamp
;
3407 bool condition_result
;
3408 bool failed_condition_trigger
;
3409 bool failed_condition_negate
;
3410 const char *failed_condition
;
3411 const char *failed_condition_parameter
;
3413 usec_t assert_timestamp
;
3415 bool failed_assert_trigger
;
3416 bool failed_assert_negate
;
3417 const char *failed_assert
;
3418 const char *failed_assert_parameter
;
3421 unsigned n_accepted
;
3422 unsigned n_connections
;
3425 /* Pairs of type, path */
3429 const char *sysfs_path
;
3431 /* Mount, Automount */
3438 uint64_t memory_current
;
3439 uint64_t memory_limit
;
3440 uint64_t cpu_usage_nsec
;
3441 uint64_t tasks_current
;
3444 LIST_HEAD(ExecStatusInfo
, exec
);
3447 static void print_status_info(
3452 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3454 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3455 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3461 /* This shows pretty information about a unit. See
3462 * print_property() for a low-level property printer */
3464 if (streq_ptr(i
->active_state
, "failed")) {
3465 active_on
= ansi_highlight_red();
3466 active_off
= ansi_normal();
3467 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3468 active_on
= ansi_highlight_green();
3469 active_off
= ansi_normal();
3471 active_on
= active_off
= "";
3473 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3475 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3476 printf(" - %s", i
->description
);
3481 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3483 if (streq_ptr(i
->load_state
, "error")) {
3484 on
= ansi_highlight_red();
3485 off
= ansi_normal();
3489 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3491 if (i
->load_error
!= 0)
3492 printf(" Loaded: %s%s%s (Reason: %s)\n",
3493 on
, strna(i
->load_state
), off
, i
->load_error
);
3494 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3495 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3496 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3497 else if (path
&& !isempty(i
->unit_file_state
))
3498 printf(" Loaded: %s%s%s (%s; %s)\n",
3499 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3501 printf(" Loaded: %s%s%s (%s)\n",
3502 on
, strna(i
->load_state
), off
, path
);
3504 printf(" Loaded: %s%s%s\n",
3505 on
, strna(i
->load_state
), off
);
3508 printf("Transient: yes\n");
3510 if (!strv_isempty(i
->dropin_paths
)) {
3511 _cleanup_free_
char *dir
= NULL
;
3515 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3516 if (! dir
|| last
) {
3517 printf(dir
? " " : " Drop-In: ");
3521 dir
= dirname_malloc(*dropin
);
3527 printf("%s\n %s", dir
,
3528 draw_special_char(DRAW_TREE_RIGHT
));
3531 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3533 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3537 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3539 printf(" Active: %s%s (%s)%s",
3540 active_on
, strna(i
->active_state
), ss
, active_off
);
3542 printf(" Active: %s%s%s",
3543 active_on
, strna(i
->active_state
), active_off
);
3545 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3546 printf(" (Result: %s)", i
->result
);
3548 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3549 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3550 (streq_ptr(i
->active_state
, "inactive") ||
3551 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3552 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3553 i
->active_exit_timestamp
;
3555 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3556 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3559 printf(" since %s; %s\n", s2
, s1
);
3561 printf(" since %s\n", s2
);
3565 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3566 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3567 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3569 printf("Condition: start %scondition failed%s at %s%s%s\n",
3570 ansi_highlight_yellow(), ansi_normal(),
3571 s2
, s1
? "; " : "", strempty(s1
));
3572 if (i
->failed_condition_trigger
)
3573 printf(" none of the trigger conditions were met\n");
3574 else if (i
->failed_condition
)
3575 printf(" %s=%s%s was not met\n",
3576 i
->failed_condition
,
3577 i
->failed_condition_negate
? "!" : "",
3578 i
->failed_condition_parameter
);
3581 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3582 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3583 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3585 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3586 ansi_highlight_red(), ansi_normal(),
3587 s2
, s1
? "; " : "", strempty(s1
));
3588 if (i
->failed_assert_trigger
)
3589 printf(" none of the trigger assertions were met\n");
3590 else if (i
->failed_assert
)
3591 printf(" %s=%s%s was not met\n",
3593 i
->failed_assert_negate
? "!" : "",
3594 i
->failed_assert_parameter
);
3598 printf(" Device: %s\n", i
->sysfs_path
);
3600 printf(" Where: %s\n", i
->where
);
3602 printf(" What: %s\n", i
->what
);
3604 STRV_FOREACH(t
, i
->documentation
)
3605 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3607 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3608 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3611 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3613 LIST_FOREACH(exec
, p
, i
->exec
) {
3614 _cleanup_free_
char *argv
= NULL
;
3617 /* Only show exited processes here */
3621 argv
= strv_join(p
->argv
, " ");
3622 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3624 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3626 on
= ansi_highlight_red();
3627 off
= ansi_normal();
3631 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3633 if (p
->code
== CLD_EXITED
) {
3636 printf("status=%i", p
->status
);
3638 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3643 printf("signal=%s", signal_to_string(p
->status
));
3645 printf(")%s\n", off
);
3647 if (i
->main_pid
== p
->pid
&&
3648 i
->start_timestamp
== p
->start_timestamp
&&
3649 i
->exit_timestamp
== p
->start_timestamp
)
3650 /* Let's not show this twice */
3653 if (p
->pid
== i
->control_pid
)
3657 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3658 if (i
->main_pid
> 0) {
3659 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3662 _cleanup_free_
char *comm
= NULL
;
3663 get_process_comm(i
->main_pid
, &comm
);
3665 printf(" (%s)", comm
);
3666 } else if (i
->exit_code
> 0) {
3667 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3669 if (i
->exit_code
== CLD_EXITED
) {
3672 printf("status=%i", i
->exit_status
);
3674 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3679 printf("signal=%s", signal_to_string(i
->exit_status
));
3683 if (i
->control_pid
> 0)
3687 if (i
->control_pid
> 0) {
3688 _cleanup_free_
char *c
= NULL
;
3690 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3692 get_process_comm(i
->control_pid
, &c
);
3701 printf(" Status: \"%s\"\n", i
->status_text
);
3702 if (i
->status_errno
> 0)
3703 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3705 if (i
->tasks_current
!= (uint64_t) -1) {
3706 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3708 if (i
->tasks_max
!= (uint64_t) -1)
3709 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3714 if (i
->memory_current
!= (uint64_t) -1) {
3715 char buf
[FORMAT_BYTES_MAX
];
3717 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3719 if (i
->memory_limit
!= (uint64_t) -1)
3720 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3725 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3726 char buf
[FORMAT_TIMESPAN_MAX
];
3727 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3730 if (i
->control_group
&&
3731 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3732 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3735 printf(" CGroup: %s\n", i
->control_group
);
3737 if (IN_SET(arg_transport
,
3738 BUS_TRANSPORT_LOCAL
,
3739 BUS_TRANSPORT_MACHINE
)) {
3742 static const char prefix
[] = " ";
3745 if (c
> sizeof(prefix
) - 1)
3746 c
-= sizeof(prefix
) - 1;
3750 if (i
->main_pid
> 0)
3751 extra
[k
++] = i
->main_pid
;
3753 if (i
->control_pid
> 0)
3754 extra
[k
++] = i
->control_pid
;
3756 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3760 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3761 show_journal_by_unit(
3766 i
->inactive_exit_timestamp_monotonic
,
3769 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3770 SD_JOURNAL_LOCAL_ONLY
,
3771 arg_scope
== UNIT_FILE_SYSTEM
,
3774 if (i
->need_daemon_reload
)
3775 warn_unit_file_changed(i
->id
);
3778 static void show_unit_help(UnitStatusInfo
*i
) {
3783 if (!i
->documentation
) {
3784 log_info("Documentation for %s not known.", i
->id
);
3788 STRV_FOREACH(p
, i
->documentation
)
3789 if (startswith(*p
, "man:"))
3790 show_man_page(*p
+ 4, false);
3792 log_info("Can't show: %s", *p
);
3795 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3802 switch (contents
[0]) {
3804 case SD_BUS_TYPE_STRING
: {
3807 r
= sd_bus_message_read(m
, "s", &s
);
3809 return bus_log_parse_error(r
);
3812 if (streq(name
, "Id"))
3814 else if (streq(name
, "LoadState"))
3816 else if (streq(name
, "ActiveState"))
3817 i
->active_state
= s
;
3818 else if (streq(name
, "SubState"))
3820 else if (streq(name
, "Description"))
3822 else if (streq(name
, "FragmentPath"))
3823 i
->fragment_path
= s
;
3824 else if (streq(name
, "SourcePath"))
3827 else if (streq(name
, "DefaultControlGroup")) {
3829 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3831 i
->control_group
= e
;
3834 else if (streq(name
, "ControlGroup"))
3835 i
->control_group
= s
;
3836 else if (streq(name
, "StatusText"))
3838 else if (streq(name
, "PIDFile"))
3840 else if (streq(name
, "SysFSPath"))
3842 else if (streq(name
, "Where"))
3844 else if (streq(name
, "What"))
3846 else if (streq(name
, "Following"))
3848 else if (streq(name
, "UnitFileState"))
3849 i
->unit_file_state
= s
;
3850 else if (streq(name
, "UnitFilePreset"))
3851 i
->unit_file_preset
= s
;
3852 else if (streq(name
, "Result"))
3859 case SD_BUS_TYPE_BOOLEAN
: {
3862 r
= sd_bus_message_read(m
, "b", &b
);
3864 return bus_log_parse_error(r
);
3866 if (streq(name
, "Accept"))
3868 else if (streq(name
, "NeedDaemonReload"))
3869 i
->need_daemon_reload
= b
;
3870 else if (streq(name
, "ConditionResult"))
3871 i
->condition_result
= b
;
3872 else if (streq(name
, "AssertResult"))
3873 i
->assert_result
= b
;
3874 else if (streq(name
, "Transient"))
3880 case SD_BUS_TYPE_UINT32
: {
3883 r
= sd_bus_message_read(m
, "u", &u
);
3885 return bus_log_parse_error(r
);
3887 if (streq(name
, "MainPID")) {
3889 i
->main_pid
= (pid_t
) u
;
3892 } else if (streq(name
, "ControlPID"))
3893 i
->control_pid
= (pid_t
) u
;
3894 else if (streq(name
, "ExecMainPID")) {
3896 i
->main_pid
= (pid_t
) u
;
3897 } else if (streq(name
, "NAccepted"))
3899 else if (streq(name
, "NConnections"))
3900 i
->n_connections
= u
;
3905 case SD_BUS_TYPE_INT32
: {
3908 r
= sd_bus_message_read(m
, "i", &j
);
3910 return bus_log_parse_error(r
);
3912 if (streq(name
, "ExecMainCode"))
3913 i
->exit_code
= (int) j
;
3914 else if (streq(name
, "ExecMainStatus"))
3915 i
->exit_status
= (int) j
;
3916 else if (streq(name
, "StatusErrno"))
3917 i
->status_errno
= (int) j
;
3922 case SD_BUS_TYPE_UINT64
: {
3925 r
= sd_bus_message_read(m
, "t", &u
);
3927 return bus_log_parse_error(r
);
3929 if (streq(name
, "ExecMainStartTimestamp"))
3930 i
->start_timestamp
= (usec_t
) u
;
3931 else if (streq(name
, "ExecMainExitTimestamp"))
3932 i
->exit_timestamp
= (usec_t
) u
;
3933 else if (streq(name
, "ActiveEnterTimestamp"))
3934 i
->active_enter_timestamp
= (usec_t
) u
;
3935 else if (streq(name
, "InactiveEnterTimestamp"))
3936 i
->inactive_enter_timestamp
= (usec_t
) u
;
3937 else if (streq(name
, "InactiveExitTimestamp"))
3938 i
->inactive_exit_timestamp
= (usec_t
) u
;
3939 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3940 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3941 else if (streq(name
, "ActiveExitTimestamp"))
3942 i
->active_exit_timestamp
= (usec_t
) u
;
3943 else if (streq(name
, "ConditionTimestamp"))
3944 i
->condition_timestamp
= (usec_t
) u
;
3945 else if (streq(name
, "AssertTimestamp"))
3946 i
->assert_timestamp
= (usec_t
) u
;
3947 else if (streq(name
, "MemoryCurrent"))
3948 i
->memory_current
= u
;
3949 else if (streq(name
, "MemoryLimit"))
3950 i
->memory_limit
= u
;
3951 else if (streq(name
, "TasksCurrent"))
3952 i
->tasks_current
= u
;
3953 else if (streq(name
, "TasksMax"))
3955 else if (streq(name
, "CPUUsageNSec"))
3956 i
->cpu_usage_nsec
= u
;
3961 case SD_BUS_TYPE_ARRAY
:
3963 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3964 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3966 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3968 return bus_log_parse_error(r
);
3970 info
= new0(ExecStatusInfo
, 1);
3974 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3976 info
->name
= strdup(name
);
3980 LIST_PREPEND(exec
, i
->exec
, info
);
3982 info
= new0(ExecStatusInfo
, 1);
3988 return bus_log_parse_error(r
);
3990 r
= sd_bus_message_exit_container(m
);
3992 return bus_log_parse_error(r
);
3996 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3997 const char *type
, *path
;
3999 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4001 return bus_log_parse_error(r
);
4003 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4005 r
= strv_extend(&i
->listen
, type
);
4009 r
= strv_extend(&i
->listen
, path
);
4014 return bus_log_parse_error(r
);
4016 r
= sd_bus_message_exit_container(m
);
4018 return bus_log_parse_error(r
);
4022 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4024 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4026 return bus_log_parse_error(r
);
4028 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4030 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4032 return bus_log_parse_error(r
);
4034 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4035 const char *cond
, *param
;
4036 int trigger
, negate
;
4039 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4041 return bus_log_parse_error(r
);
4043 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4044 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4045 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4046 i
->failed_condition
= cond
;
4047 i
->failed_condition_trigger
= trigger
;
4048 i
->failed_condition_negate
= negate
;
4049 i
->failed_condition_parameter
= param
;
4053 return bus_log_parse_error(r
);
4055 r
= sd_bus_message_exit_container(m
);
4057 return bus_log_parse_error(r
);
4059 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4060 const char *cond
, *param
;
4061 int trigger
, negate
;
4064 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4066 return bus_log_parse_error(r
);
4068 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4069 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4070 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4071 i
->failed_assert
= cond
;
4072 i
->failed_assert_trigger
= trigger
;
4073 i
->failed_assert_negate
= negate
;
4074 i
->failed_assert_parameter
= param
;
4078 return bus_log_parse_error(r
);
4080 r
= sd_bus_message_exit_container(m
);
4082 return bus_log_parse_error(r
);
4089 case SD_BUS_TYPE_STRUCT_BEGIN
:
4091 if (streq(name
, "LoadError")) {
4092 const char *n
, *message
;
4094 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4096 return bus_log_parse_error(r
);
4098 if (!isempty(message
))
4099 i
->load_error
= message
;
4112 r
= sd_bus_message_skip(m
, contents
);
4114 return bus_log_parse_error(r
);
4119 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4125 /* This is a low-level property printer, see
4126 * print_status_info() for the nicer output */
4128 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4129 /* skip what we didn't read */
4130 r
= sd_bus_message_skip(m
, contents
);
4134 switch (contents
[0]) {
4136 case SD_BUS_TYPE_STRUCT_BEGIN
:
4138 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4141 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4143 return bus_log_parse_error(r
);
4146 printf("%s=%"PRIu32
"\n", name
, u
);
4148 printf("%s=\n", name
);
4152 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4155 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4157 return bus_log_parse_error(r
);
4159 if (arg_all
|| !isempty(s
))
4160 printf("%s=%s\n", name
, s
);
4164 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4165 const char *a
= NULL
, *b
= NULL
;
4167 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4169 return bus_log_parse_error(r
);
4171 if (arg_all
|| !isempty(a
) || !isempty(b
))
4172 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4175 } else if (streq_ptr(name
, "SystemCallFilter")) {
4176 _cleanup_strv_free_
char **l
= NULL
;
4179 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4181 return bus_log_parse_error(r
);
4183 r
= sd_bus_message_read(m
, "b", &whitelist
);
4185 return bus_log_parse_error(r
);
4187 r
= sd_bus_message_read_strv(m
, &l
);
4189 return bus_log_parse_error(r
);
4191 r
= sd_bus_message_exit_container(m
);
4193 return bus_log_parse_error(r
);
4195 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4199 fputs(name
, stdout
);
4205 STRV_FOREACH(i
, l
) {
4213 fputc('\n', stdout
);
4221 case SD_BUS_TYPE_ARRAY
:
4223 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4227 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4229 return bus_log_parse_error(r
);
4231 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4232 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4235 return bus_log_parse_error(r
);
4237 r
= sd_bus_message_exit_container(m
);
4239 return bus_log_parse_error(r
);
4243 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4244 const char *type
, *path
;
4246 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4248 return bus_log_parse_error(r
);
4250 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4251 printf("%s=%s\n", type
, path
);
4253 return bus_log_parse_error(r
);
4255 r
= sd_bus_message_exit_container(m
);
4257 return bus_log_parse_error(r
);
4261 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4262 const char *type
, *path
;
4264 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4266 return bus_log_parse_error(r
);
4268 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4269 printf("Listen%s=%s\n", type
, path
);
4271 return bus_log_parse_error(r
);
4273 r
= sd_bus_message_exit_container(m
);
4275 return bus_log_parse_error(r
);
4279 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4281 uint64_t value
, next_elapse
;
4283 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4285 return bus_log_parse_error(r
);
4287 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4288 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4290 printf("%s={ value=%s ; next_elapse=%s }\n",
4292 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4293 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4296 return bus_log_parse_error(r
);
4298 r
= sd_bus_message_exit_container(m
);
4300 return bus_log_parse_error(r
);
4304 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4305 ExecStatusInfo info
= {};
4307 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4309 return bus_log_parse_error(r
);
4311 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4312 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4313 _cleanup_free_
char *tt
;
4315 tt
= strv_join(info
.argv
, " ");
4317 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }\n",
4321 yes_no(info
.ignore
),
4322 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4323 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4325 sigchld_code_to_string(info
.code
),
4327 info
.code
== CLD_EXITED
? "" : "/",
4328 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4331 strv_free(info
.argv
);
4335 r
= sd_bus_message_exit_container(m
);
4337 return bus_log_parse_error(r
);
4341 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4342 const char *path
, *rwm
;
4344 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4346 return bus_log_parse_error(r
);
4348 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4349 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4351 return bus_log_parse_error(r
);
4353 r
= sd_bus_message_exit_container(m
);
4355 return bus_log_parse_error(r
);
4359 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4363 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4365 return bus_log_parse_error(r
);
4367 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4368 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4370 return bus_log_parse_error(r
);
4372 r
= sd_bus_message_exit_container(m
);
4374 return bus_log_parse_error(r
);
4378 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4382 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4384 return bus_log_parse_error(r
);
4386 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4387 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4389 return bus_log_parse_error(r
);
4391 r
= sd_bus_message_exit_container(m
);
4393 return bus_log_parse_error(r
);
4401 r
= bus_print_property(name
, m
, arg_all
);
4403 return bus_log_parse_error(r
);
4406 r
= sd_bus_message_skip(m
, contents
);
4408 return bus_log_parse_error(r
);
4411 printf("%s=[unprintable]\n", name
);
4417 static int show_one(
4421 bool show_properties
,
4425 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4426 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4427 UnitStatusInfo info
= {
4428 .memory_current
= (uint64_t) -1,
4429 .memory_limit
= (uint64_t) -1,
4430 .cpu_usage_nsec
= (uint64_t) -1,
4431 .tasks_current
= (uint64_t) -1,
4432 .tasks_max
= (uint64_t) -1,
4440 log_debug("Showing one %s", path
);
4442 r
= sd_bus_call_method(
4444 "org.freedesktop.systemd1",
4446 "org.freedesktop.DBus.Properties",
4452 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4454 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4456 return bus_log_parse_error(r
);
4463 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4464 const char *name
, *contents
;
4466 r
= sd_bus_message_read(reply
, "s", &name
);
4468 return bus_log_parse_error(r
);
4470 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4472 return bus_log_parse_error(r
);
4474 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4476 return bus_log_parse_error(r
);
4478 if (show_properties
)
4479 r
= print_property(name
, reply
, contents
);
4481 r
= status_property(name
, reply
, &info
, contents
);
4485 r
= sd_bus_message_exit_container(reply
);
4487 return bus_log_parse_error(r
);
4489 r
= sd_bus_message_exit_container(reply
);
4491 return bus_log_parse_error(r
);
4494 return bus_log_parse_error(r
);
4496 r
= sd_bus_message_exit_container(reply
);
4498 return bus_log_parse_error(r
);
4502 if (!show_properties
) {
4503 if (streq(verb
, "help"))
4504 show_unit_help(&info
);
4506 print_status_info(&info
, ellipsized
);
4509 strv_free(info
.documentation
);
4510 strv_free(info
.dropin_paths
);
4511 strv_free(info
.listen
);
4513 if (!streq_ptr(info
.active_state
, "active") &&
4514 !streq_ptr(info
.active_state
, "reloading") &&
4515 streq(verb
, "status")) {
4516 /* According to LSB: "program not running" */
4517 /* 0: program is running or service is OK
4518 * 1: program is dead and /run PID file exists
4519 * 2: program is dead and /run/lock lock file exists
4520 * 3: program is not running
4521 * 4: program or service status is unknown
4523 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4529 while ((p
= info
.exec
)) {
4530 LIST_REMOVE(exec
, info
.exec
, p
);
4531 exec_status_info_free(p
);
4537 static int get_unit_dbus_path_by_pid(
4542 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4543 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4547 r
= sd_bus_call_method(
4549 "org.freedesktop.systemd1",
4550 "/org/freedesktop/systemd1",
4551 "org.freedesktop.systemd1.Manager",
4557 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4559 r
= sd_bus_message_read(reply
, "o", &u
);
4561 return bus_log_parse_error(r
);
4571 static int show_all(
4574 bool show_properties
,
4578 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4579 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4584 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4588 pager_open(arg_no_pager
, false);
4592 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4594 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4595 _cleanup_free_
char *p
= NULL
;
4597 p
= unit_dbus_path_from_name(u
->id
);
4601 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4604 else if (r
> 0 && ret
== 0)
4611 static int show_system_status(sd_bus
*bus
) {
4612 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4613 _cleanup_free_
char *hn
= NULL
;
4614 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4615 const char *on
, *off
;
4618 hn
= gethostname_malloc();
4622 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4624 return log_error_errno(r
, "Failed to read server status: %m");
4626 if (streq_ptr(mi
.state
, "degraded")) {
4627 on
= ansi_highlight_red();
4628 off
= ansi_normal();
4629 } else if (!streq_ptr(mi
.state
, "running")) {
4630 on
= ansi_highlight_yellow();
4631 off
= ansi_normal();
4635 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4637 printf(" State: %s%s%s\n",
4638 on
, strna(mi
.state
), off
);
4640 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
4641 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
4643 printf(" Since: %s; %s\n",
4644 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4645 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4647 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4648 if (IN_SET(arg_transport
,
4649 BUS_TRANSPORT_LOCAL
,
4650 BUS_TRANSPORT_MACHINE
)) {
4651 static const char prefix
[] = " ";
4655 if (c
> sizeof(prefix
) - 1)
4656 c
-= sizeof(prefix
) - 1;
4660 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4666 static int show(int argc
, char *argv
[], void *userdata
) {
4667 bool show_properties
, show_status
, show_help
, new_line
= false;
4668 bool ellipsized
= false;
4674 show_properties
= streq(argv
[0], "show");
4675 show_status
= streq(argv
[0], "status");
4676 show_help
= streq(argv
[0], "help");
4678 if (show_help
&& argc
<= 1) {
4679 log_error("This command expects one or more unit names. Did you mean --help?");
4683 pager_open(arg_no_pager
, false);
4686 /* Increase max number of open files to 16K if we can, we
4687 * might needs this when browsing journal files, which might
4688 * be split up into many files. */
4689 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4691 r
= acquire_bus(BUS_MANAGER
, &bus
);
4695 /* If no argument is specified inspect the manager itself */
4696 if (show_properties
&& argc
<= 1)
4697 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4699 if (show_status
&& argc
<= 1) {
4701 pager_open(arg_no_pager
, false);
4702 show_system_status(bus
);
4706 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4708 _cleanup_free_
char **patterns
= NULL
;
4711 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4712 _cleanup_free_
char *unit
= NULL
;
4715 if (safe_atou32(*name
, &id
) < 0) {
4716 if (strv_push(&patterns
, *name
) < 0)
4720 } else if (show_properties
) {
4721 /* Interpret as job id */
4722 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4726 /* Interpret as PID */
4727 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4734 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4737 else if (r
> 0 && ret
== 0)
4741 if (!strv_isempty(patterns
)) {
4742 _cleanup_strv_free_
char **names
= NULL
;
4744 r
= expand_names(bus
, patterns
, NULL
, &names
);
4746 return log_error_errno(r
, "Failed to expand names: %m");
4748 STRV_FOREACH(name
, names
) {
4749 _cleanup_free_
char *unit
;
4751 unit
= unit_dbus_path_from_name(*name
);
4755 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4758 else if (r
> 0 && ret
== 0)
4764 if (ellipsized
&& !arg_quiet
)
4765 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4770 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4774 assert(user_runtime
);
4777 if (arg_scope
== UNIT_FILE_USER
) {
4778 r
= user_config_home(user_home
);
4780 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4782 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4784 r
= user_runtime_dir(user_runtime
);
4786 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4788 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4791 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4793 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4798 static int cat_file(const char *filename
, bool newline
) {
4799 _cleanup_close_
int fd
;
4801 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4805 printf("%s%s# %s%s\n",
4806 newline
? "\n" : "",
4807 ansi_highlight_blue(),
4812 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4815 static int cat(int argc
, char *argv
[], void *userdata
) {
4816 _cleanup_free_
char *user_home
= NULL
;
4817 _cleanup_free_
char *user_runtime
= NULL
;
4818 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4819 _cleanup_strv_free_
char **names
= NULL
;
4825 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4826 log_error("Cannot remotely cat units.");
4830 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4834 r
= acquire_bus(BUS_MANAGER
, &bus
);
4838 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4840 return log_error_errno(r
, "Failed to expand names: %m");
4842 pager_open(arg_no_pager
, false);
4844 STRV_FOREACH(name
, names
) {
4845 _cleanup_free_
char *fragment_path
= NULL
;
4846 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4849 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4860 if (fragment_path
) {
4861 r
= cat_file(fragment_path
, false);
4863 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4866 STRV_FOREACH(path
, dropin_paths
) {
4867 r
= cat_file(*path
, path
== dropin_paths
);
4869 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4876 static int set_property(int argc
, char *argv
[], void *userdata
) {
4877 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4878 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4879 _cleanup_free_
char *n
= NULL
;
4884 polkit_agent_open_if_enabled();
4886 r
= acquire_bus(BUS_MANAGER
, &bus
);
4890 r
= sd_bus_message_new_method_call(
4893 "org.freedesktop.systemd1",
4894 "/org/freedesktop/systemd1",
4895 "org.freedesktop.systemd1.Manager",
4896 "SetUnitProperties");
4898 return bus_log_create_error(r
);
4900 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4902 return log_error_errno(r
, "Failed to mangle unit name: %m");
4904 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4906 return bus_log_create_error(r
);
4908 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4910 return bus_log_create_error(r
);
4912 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4913 r
= bus_append_unit_property_assignment(m
, *i
);
4918 r
= sd_bus_message_close_container(m
);
4920 return bus_log_create_error(r
);
4922 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4924 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4929 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4930 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4935 polkit_agent_open_if_enabled();
4937 r
= acquire_bus(BUS_MANAGER
, &bus
);
4941 if (arg_action
== ACTION_RELOAD
)
4943 else if (arg_action
== ACTION_REEXEC
)
4944 method
= "Reexecute";
4946 assert(arg_action
== ACTION_SYSTEMCTL
);
4949 streq(argv
[0], "clear-jobs") ||
4950 streq(argv
[0], "cancel") ? "ClearJobs" :
4951 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4952 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4953 streq(argv
[0], "halt") ? "Halt" :
4954 streq(argv
[0], "poweroff") ? "PowerOff" :
4955 streq(argv
[0], "reboot") ? "Reboot" :
4956 streq(argv
[0], "kexec") ? "KExec" :
4957 streq(argv
[0], "exit") ? "Exit" :
4958 /* "daemon-reload" */ "Reload";
4961 r
= sd_bus_call_method(
4963 "org.freedesktop.systemd1",
4964 "/org/freedesktop/systemd1",
4965 "org.freedesktop.systemd1.Manager",
4970 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4971 /* There's always a fallback possible for
4972 * legacy actions. */
4974 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4975 /* On reexecution, we expect a disconnect, not a
4979 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
4981 return r
< 0 ? r
: 0;
4984 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4985 _cleanup_strv_free_
char **names
= NULL
;
4991 return daemon_reload(argc
, argv
, userdata
);
4993 polkit_agent_open_if_enabled();
4995 r
= acquire_bus(BUS_MANAGER
, &bus
);
4999 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5001 return log_error_errno(r
, "Failed to expand names: %m");
5003 STRV_FOREACH(name
, names
) {
5004 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5006 q
= sd_bus_call_method(
5008 "org.freedesktop.systemd1",
5009 "/org/freedesktop/systemd1",
5010 "org.freedesktop.systemd1.Manager",
5016 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5025 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5026 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5027 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5032 pager_open(arg_no_pager
, false);
5034 r
= acquire_bus(BUS_MANAGER
, &bus
);
5038 r
= sd_bus_get_property(
5040 "org.freedesktop.systemd1",
5041 "/org/freedesktop/systemd1",
5042 "org.freedesktop.systemd1.Manager",
5048 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5050 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5052 return bus_log_parse_error(r
);
5054 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5057 return bus_log_parse_error(r
);
5059 r
= sd_bus_message_exit_container(reply
);
5061 return bus_log_parse_error(r
);
5066 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5067 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5068 _cleanup_free_
char *cmdline_init
= NULL
;
5069 const char *root
, *init
;
5073 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5074 log_error("Cannot switch root remotely.");
5078 if (argc
< 2 || argc
> 3) {
5079 log_error("Wrong number of arguments.");
5088 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5089 "init", &cmdline_init
,
5092 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5094 init
= cmdline_init
;
5101 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5103 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5104 root_init_path
= strjoina(root
, "/", init
);
5106 /* If the passed init is actually the same as the
5107 * systemd binary, then let's suppress it. */
5108 if (files_same(root_init_path
, root_systemd_path
) > 0)
5112 r
= acquire_bus(BUS_MANAGER
, &bus
);
5116 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5118 r
= sd_bus_call_method(
5120 "org.freedesktop.systemd1",
5121 "/org/freedesktop/systemd1",
5122 "org.freedesktop.systemd1.Manager",
5128 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5133 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5134 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5135 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5143 polkit_agent_open_if_enabled();
5145 r
= acquire_bus(BUS_MANAGER
, &bus
);
5149 method
= streq(argv
[0], "set-environment")
5151 : "UnsetEnvironment";
5153 r
= sd_bus_message_new_method_call(
5156 "org.freedesktop.systemd1",
5157 "/org/freedesktop/systemd1",
5158 "org.freedesktop.systemd1.Manager",
5161 return bus_log_create_error(r
);
5163 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5165 return bus_log_create_error(r
);
5167 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5169 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5174 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5175 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5176 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5180 polkit_agent_open_if_enabled();
5182 r
= acquire_bus(BUS_MANAGER
, &bus
);
5186 r
= sd_bus_message_new_method_call(
5189 "org.freedesktop.systemd1",
5190 "/org/freedesktop/systemd1",
5191 "org.freedesktop.systemd1.Manager",
5194 return bus_log_create_error(r
);
5197 r
= sd_bus_message_append_strv(m
, environ
);
5201 r
= sd_bus_message_open_container(m
, 'a', "s");
5203 return bus_log_create_error(r
);
5205 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5207 if (!env_name_is_valid(*a
)) {
5208 log_error("Not a valid environment variable name: %s", *a
);
5212 STRV_FOREACH(b
, environ
) {
5215 eq
= startswith(*b
, *a
);
5216 if (eq
&& *eq
== '=') {
5218 r
= sd_bus_message_append(m
, "s", *b
);
5220 return bus_log_create_error(r
);
5227 r
= sd_bus_message_close_container(m
);
5230 return bus_log_create_error(r
);
5232 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5234 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5239 static int enable_sysv_units(const char *verb
, char **args
) {
5242 #if defined(HAVE_SYSV_COMPAT)
5244 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5246 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5249 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5252 if (!STR_IN_SET(verb
,
5258 /* Processes all SysV units, and reshuffles the array so that
5259 * afterwards only the native units remain */
5261 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5268 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5269 bool found_native
= false, found_sysv
;
5271 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5279 if (!endswith(name
, ".service"))
5282 if (path_is_absolute(name
))
5285 STRV_FOREACH(k
, paths
.unit_path
) {
5286 _cleanup_free_
char *path
= NULL
;
5288 path
= path_join(arg_root
, *k
, name
);
5292 found_native
= access(path
, F_OK
) >= 0;
5297 /* If we have both a native unit and a SysV script,
5298 * enable/disable them both (below); for is-enabled, prefer the
5300 if (found_native
&& streq(verb
, "is-enabled"))
5303 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5307 p
[strlen(p
) - strlen(".service")] = 0;
5308 found_sysv
= access(p
, F_OK
) >= 0;
5313 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5315 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5317 if (!isempty(arg_root
))
5318 argv
[c
++] = q
= strappend("--root=", arg_root
);
5321 argv
[c
++] = basename(p
);
5324 l
= strv_join((char**)argv
, " ");
5328 log_info("Executing %s", l
);
5332 return log_error_errno(errno
, "Failed to fork: %m");
5333 else if (pid
== 0) {
5336 (void) reset_all_signal_handlers();
5337 (void) reset_signal_mask();
5339 execv(argv
[0], (char**) argv
);
5340 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5341 _exit(EXIT_FAILURE
);
5344 j
= wait_for_terminate(pid
, &status
);
5346 log_error_errno(j
, "Failed to wait for child: %m");
5350 if (status
.si_code
== CLD_EXITED
) {
5351 if (streq(verb
, "is-enabled")) {
5352 if (status
.si_status
== 0) {
5361 } else if (status
.si_status
!= 0)
5369 /* Remove this entry, so that we don't try enabling it as native unit */
5372 assert(args
[f
] == name
);
5373 strv_remove(args
, name
);
5380 static int mangle_names(char **original_names
, char ***mangled_names
) {
5381 char **i
, **l
, **name
;
5384 l
= i
= new(char*, strv_length(original_names
) + 1);
5388 STRV_FOREACH(name
, original_names
) {
5390 /* When enabling units qualified path names are OK,
5391 * too, hence allow them explicitly. */
5393 if (is_path(*name
)) {
5400 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5403 return log_error_errno(r
, "Failed to mangle unit name: %m");
5416 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5417 _cleanup_strv_free_
char **names
= NULL
;
5418 const char *verb
= argv
[0];
5419 UnitFileChange
*changes
= NULL
;
5420 unsigned n_changes
= 0;
5421 int carries_install_info
= -1;
5427 r
= mangle_names(strv_skip(argv
, 1), &names
);
5431 r
= enable_sysv_units(verb
, names
);
5435 /* If the operation was fully executed by the SysV compat,
5436 * let's finish early */
5437 if (strv_isempty(names
))
5440 if (install_client_side()) {
5441 if (streq(verb
, "enable")) {
5442 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5443 carries_install_info
= r
;
5444 } else if (streq(verb
, "disable"))
5445 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5446 else if (streq(verb
, "reenable")) {
5447 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5448 carries_install_info
= r
;
5449 } else if (streq(verb
, "link"))
5450 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5451 else if (streq(verb
, "preset")) {
5452 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5453 carries_install_info
= r
;
5454 } else if (streq(verb
, "mask"))
5455 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5456 else if (streq(verb
, "unmask"))
5457 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5459 assert_not_reached("Unknown verb");
5461 if (r
== -ESHUTDOWN
)
5462 return log_error_errno(r
, "Unit file is masked.");
5464 return log_error_errno(r
, "Operation failed: %m");
5467 dump_unit_file_changes(changes
, n_changes
);
5471 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5472 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5473 int expect_carries_install_info
= false;
5474 bool send_force
= true, send_preset_mode
= false;
5478 polkit_agent_open_if_enabled();
5480 r
= acquire_bus(BUS_MANAGER
, &bus
);
5484 if (streq(verb
, "enable")) {
5485 method
= "EnableUnitFiles";
5486 expect_carries_install_info
= true;
5487 } else if (streq(verb
, "disable")) {
5488 method
= "DisableUnitFiles";
5490 } else if (streq(verb
, "reenable")) {
5491 method
= "ReenableUnitFiles";
5492 expect_carries_install_info
= true;
5493 } else if (streq(verb
, "link"))
5494 method
= "LinkUnitFiles";
5495 else if (streq(verb
, "preset")) {
5497 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5498 method
= "PresetUnitFilesWithMode";
5499 send_preset_mode
= true;
5501 method
= "PresetUnitFiles";
5503 expect_carries_install_info
= true;
5504 } else if (streq(verb
, "mask"))
5505 method
= "MaskUnitFiles";
5506 else if (streq(verb
, "unmask")) {
5507 method
= "UnmaskUnitFiles";
5510 assert_not_reached("Unknown verb");
5512 r
= sd_bus_message_new_method_call(
5515 "org.freedesktop.systemd1",
5516 "/org/freedesktop/systemd1",
5517 "org.freedesktop.systemd1.Manager",
5520 return bus_log_create_error(r
);
5522 r
= sd_bus_message_append_strv(m
, names
);
5524 return bus_log_create_error(r
);
5526 if (send_preset_mode
) {
5527 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5529 return bus_log_create_error(r
);
5532 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5534 return bus_log_create_error(r
);
5537 r
= sd_bus_message_append(m
, "b", arg_force
);
5539 return bus_log_create_error(r
);
5542 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5544 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5546 if (expect_carries_install_info
) {
5547 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5549 return bus_log_parse_error(r
);
5552 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5556 /* Try to reload if enabled */
5558 r
= daemon_reload(argc
, argv
, userdata
);
5563 if (carries_install_info
== 0)
5564 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5565 "using systemctl.\n"
5566 "Possible reasons for having this kind of units are:\n"
5567 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5568 " .wants/ or .requires/ directory.\n"
5569 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5570 " a requirement dependency on it.\n"
5571 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5572 " D-Bus, udev, scripted systemctl call, ...).\n");
5574 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5575 char *new_args
[n_changes
+ 2];
5579 r
= acquire_bus(BUS_MANAGER
, &bus
);
5583 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5584 for (i
= 0; i
< n_changes
; i
++)
5585 new_args
[i
+ 1] = basename(changes
[i
].path
);
5586 new_args
[i
+ 1] = NULL
;
5588 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5592 unit_file_changes_free(changes
, n_changes
);
5597 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5598 _cleanup_strv_free_
char **names
= NULL
;
5599 _cleanup_free_
char *target
= NULL
;
5600 const char *verb
= argv
[0];
5607 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5609 return log_error_errno(r
, "Failed to mangle unit name: %m");
5611 r
= mangle_names(strv_skip(argv
, 2), &names
);
5615 if (streq(verb
, "add-wants"))
5617 else if (streq(verb
, "add-requires"))
5618 dep
= UNIT_REQUIRES
;
5620 assert_not_reached("Unknown verb");
5622 if (install_client_side()) {
5623 UnitFileChange
*changes
= NULL
;
5624 unsigned n_changes
= 0;
5626 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5627 if (r
== -ESHUTDOWN
)
5628 return log_error_errno(r
, "Unit file is masked.");
5630 return log_error_errno(r
, "Can't add dependency: %m");
5633 dump_unit_file_changes(changes
, n_changes
);
5635 unit_file_changes_free(changes
, n_changes
);
5638 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5639 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5642 polkit_agent_open_if_enabled();
5644 r
= acquire_bus(BUS_MANAGER
, &bus
);
5648 r
= sd_bus_message_new_method_call(
5651 "org.freedesktop.systemd1",
5652 "/org/freedesktop/systemd1",
5653 "org.freedesktop.systemd1.Manager",
5654 "AddDependencyUnitFiles");
5656 return bus_log_create_error(r
);
5658 r
= sd_bus_message_append_strv(m
, names
);
5660 return bus_log_create_error(r
);
5662 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5664 return bus_log_create_error(r
);
5666 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5668 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5670 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5675 r
= daemon_reload(argc
, argv
, userdata
);
5683 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5684 UnitFileChange
*changes
= NULL
;
5685 unsigned n_changes
= 0;
5688 if (install_client_side()) {
5690 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5692 log_error_errno(r
, "Operation failed: %m");
5697 dump_unit_file_changes(changes
, n_changes
);
5702 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5703 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5706 polkit_agent_open_if_enabled();
5708 r
= acquire_bus(BUS_MANAGER
, &bus
);
5712 r
= sd_bus_call_method(
5714 "org.freedesktop.systemd1",
5715 "/org/freedesktop/systemd1",
5716 "org.freedesktop.systemd1.Manager",
5717 "PresetAllUnitFiles",
5721 unit_file_preset_mode_to_string(arg_preset_mode
),
5725 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5727 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5732 r
= daemon_reload(argc
, argv
, userdata
);
5738 unit_file_changes_free(changes
, n_changes
);
5743 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5745 _cleanup_strv_free_
char **names
= NULL
;
5750 r
= mangle_names(strv_skip(argv
, 1), &names
);
5754 r
= enable_sysv_units(argv
[0], names
);
5760 if (install_client_side()) {
5762 STRV_FOREACH(name
, names
) {
5763 UnitFileState state
;
5765 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5767 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5771 UNIT_FILE_ENABLED_RUNTIME
,
5773 UNIT_FILE_INDIRECT
))
5777 puts(unit_file_state_to_string(state
));
5781 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5784 r
= acquire_bus(BUS_MANAGER
, &bus
);
5788 STRV_FOREACH(name
, names
) {
5789 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5792 r
= sd_bus_call_method(
5794 "org.freedesktop.systemd1",
5795 "/org/freedesktop/systemd1",
5796 "org.freedesktop.systemd1.Manager",
5802 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5804 r
= sd_bus_message_read(reply
, "s", &s
);
5806 return bus_log_parse_error(r
);
5808 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5819 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5820 _cleanup_free_
char *state
= NULL
;
5824 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
5827 return EXIT_FAILURE
;
5830 r
= acquire_bus(BUS_MANAGER
, &bus
);
5834 r
= sd_bus_get_property_string(
5836 "org.freedesktop.systemd1",
5837 "/org/freedesktop/systemd1",
5838 "org.freedesktop.systemd1.Manager",
5851 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5854 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5855 _cleanup_free_
char *t
= NULL
;
5859 assert(original_path
);
5862 r
= tempfn_random(new_path
, NULL
, &t
);
5864 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5866 r
= mkdir_parents(new_path
, 0755);
5868 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5870 r
= copy_file(original_path
, t
, 0, 0644, 0);
5875 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5878 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5886 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5887 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5892 switch (arg_scope
) {
5893 case UNIT_FILE_SYSTEM
:
5894 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5896 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5898 case UNIT_FILE_GLOBAL
:
5899 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5901 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5903 case UNIT_FILE_USER
:
5905 assert(user_runtime
);
5907 path
= path_join(arg_root
, user_home
, name
);
5909 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5912 run
= path_join(arg_root
, user_runtime
, name
);
5916 assert_not_reached("Invalid scope");
5918 if (!path
|| (arg_runtime
&& !run
))
5922 if (access(path
, F_OK
) >= 0) {
5923 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5927 if (path2
&& access(path2
, F_OK
) >= 0) {
5928 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5942 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
) {
5943 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5947 assert(ret_new_path
);
5948 assert(ret_tmp_path
);
5950 ending
= strjoina(unit_name
, ".d/override.conf");
5951 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5955 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5961 *ret_new_path
= tmp_new_path
;
5962 *ret_tmp_path
= tmp_tmp_path
;
5967 static int unit_file_create_copy(
5968 const char *unit_name
,
5969 const char *fragment_path
,
5970 const char *user_home
,
5971 const char *user_runtime
,
5972 char **ret_new_path
,
5973 char **ret_tmp_path
) {
5975 char *tmp_new_path
, *tmp_tmp_path
;
5978 assert(fragment_path
);
5980 assert(ret_new_path
);
5981 assert(ret_tmp_path
);
5983 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5987 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5990 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5995 if (response
!= 'y') {
5996 log_warning("%s ignored", unit_name
);
6002 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6004 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6009 *ret_new_path
= tmp_new_path
;
6010 *ret_tmp_path
= tmp_tmp_path
;
6015 static int run_editor(char **paths
) {
6023 return log_error_errno(errno
, "Failed to fork: %m");
6027 char *editor
, **editor_args
= NULL
;
6028 char **tmp_path
, **original_path
, *p
;
6029 unsigned n_editor_args
= 0, i
= 1;
6032 (void) reset_all_signal_handlers();
6033 (void) reset_signal_mask();
6035 argc
= strv_length(paths
)/2 + 1;
6037 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6038 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6039 * we try to execute well known editors
6041 editor
= getenv("SYSTEMD_EDITOR");
6043 editor
= getenv("EDITOR");
6045 editor
= getenv("VISUAL");
6047 if (!isempty(editor
)) {
6048 editor_args
= strv_split(editor
, WHITESPACE
);
6051 _exit(EXIT_FAILURE
);
6053 n_editor_args
= strv_length(editor_args
);
6054 argc
+= n_editor_args
- 1;
6056 args
= newa(const char*, argc
+ 1);
6058 if (n_editor_args
> 0) {
6059 args
[0] = editor_args
[0];
6060 for (; i
< n_editor_args
; i
++)
6061 args
[i
] = editor_args
[i
];
6064 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6065 args
[i
] = *tmp_path
;
6070 if (n_editor_args
> 0)
6071 execvp(args
[0], (char* const*) args
);
6073 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6075 execvp(p
, (char* const*) args
);
6076 /* We do not fail if the editor doesn't exist
6077 * because we want to try each one of them before
6080 if (errno
!= ENOENT
) {
6081 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6082 _exit(EXIT_FAILURE
);
6086 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6087 _exit(EXIT_FAILURE
);
6090 r
= wait_for_terminate_and_warn("editor", pid
, true);
6092 return log_error_errno(r
, "Failed to wait for child: %m");
6097 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6098 _cleanup_free_
char *user_home
= NULL
;
6099 _cleanup_free_
char *user_runtime
= NULL
;
6100 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6107 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6111 STRV_FOREACH(name
, names
) {
6112 _cleanup_free_
char *path
= NULL
;
6113 char *new_path
, *tmp_path
;
6115 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6121 // FIXME: support units with path==NULL (no FragmentPath)
6122 log_error("No fragment exists for %s.", *name
);
6127 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6129 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6133 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6141 static int edit(int argc
, char *argv
[], void *userdata
) {
6142 _cleanup_strv_free_
char **names
= NULL
;
6143 _cleanup_strv_free_
char **paths
= NULL
;
6144 char **original
, **tmp
;
6149 log_error("Cannot edit units if not on a tty.");
6153 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6154 log_error("Cannot edit units remotely.");
6158 r
= acquire_bus(BUS_MANAGER
, &bus
);
6162 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6164 return log_error_errno(r
, "Failed to expand names: %m");
6166 r
= find_paths_to_edit(bus
, names
, &paths
);
6170 if (strv_isempty(paths
))
6173 r
= run_editor(paths
);
6177 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6178 /* If the temporary file is empty we ignore it. It's
6179 * useful if the user wants to cancel its modification
6181 if (null_or_empty_path(*tmp
)) {
6182 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6186 r
= rename(*tmp
, *original
);
6188 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6195 if (!arg_no_reload
&& !install_client_side())
6196 r
= daemon_reload(argc
, argv
, userdata
);
6199 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6200 (void) unlink(*tmp
);
6202 /* Removing empty dropin dirs */
6204 _cleanup_free_
char *dir
;
6206 dir
= dirname_malloc(*original
);
6210 /* no need to check if the dir is empty, rmdir
6211 * does nothing if it is not the case.
6220 static void systemctl_help(void) {
6222 pager_open(arg_no_pager
, false);
6224 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6225 "Query or send control commands to the systemd manager.\n\n"
6226 " -h --help Show this help\n"
6227 " --version Show package version\n"
6228 " --system Connect to system manager\n"
6229 " --user Connect to user service manager\n"
6230 " -H --host=[USER@]HOST\n"
6231 " Operate on remote host\n"
6232 " -M --machine=CONTAINER\n"
6233 " Operate on local container\n"
6234 " -t --type=TYPE List units of a particular type\n"
6235 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6236 " -p --property=NAME Show only properties by this name\n"
6237 " -a --all Show all loaded units/properties, including dead/empty\n"
6238 " ones. To list all units installed on the system, use\n"
6239 " the 'list-unit-files' command instead.\n"
6240 " -l --full Don't ellipsize unit names on output\n"
6241 " -r --recursive Show unit list of host and local containers\n"
6242 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6243 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6244 " queueing a new job\n"
6245 " --show-types When showing sockets, explicitly show their type\n"
6246 " -i --ignore-inhibitors\n"
6247 " When shutting down or sleeping, ignore inhibitors\n"
6248 " --kill-who=WHO Who to send signal to\n"
6249 " -s --signal=SIGNAL Which signal to send\n"
6250 " --now Start or stop unit in addition to enabling or disabling it\n"
6251 " -q --quiet Suppress output\n"
6252 " --no-block Do not wait until operation finished\n"
6253 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6254 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6255 " --no-legend Do not print a legend (column headers and hints)\n"
6256 " --no-pager Do not pipe output into a pager\n"
6257 " --no-ask-password\n"
6258 " Do not ask for system passwords\n"
6259 " --global Enable/disable unit files globally\n"
6260 " --runtime Enable unit files only temporarily until next reboot\n"
6261 " -f --force When enabling unit files, override existing symlinks\n"
6262 " When shutting down, execute action immediately\n"
6263 " --preset-mode= Apply only enable, only disable, or all presets\n"
6264 " --root=PATH Enable unit files in the specified root directory\n"
6265 " -n --lines=INTEGER Number of journal entries to show\n"
6266 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6267 " short-precise, short-monotonic, verbose,\n"
6268 " export, json, json-pretty, json-sse, cat)\n"
6269 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6270 " --plain Print unit dependencies as a list instead of a tree\n\n"
6272 " list-units [PATTERN...] List loaded units\n"
6273 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6274 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6275 " start NAME... Start (activate) one or more units\n"
6276 " stop NAME... Stop (deactivate) one or more units\n"
6277 " reload NAME... Reload one or more units\n"
6278 " restart NAME... Start or restart one or more units\n"
6279 " try-restart NAME... Restart one or more units if active\n"
6280 " reload-or-restart NAME... Reload one or more units if possible,\n"
6281 " otherwise start or restart\n"
6282 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6283 " if supported, otherwise restart\n"
6284 " isolate NAME Start one unit and stop all others\n"
6285 " kill NAME... Send signal to processes of a unit\n"
6286 " is-active PATTERN... Check whether units are active\n"
6287 " is-failed PATTERN... Check whether units are failed\n"
6288 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6289 " show [PATTERN...|JOB...] Show properties of one or more\n"
6290 " units/jobs or the manager\n"
6291 " cat PATTERN... Show files and drop-ins of one or more units\n"
6292 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6293 " help PATTERN...|PID... Show manual for one or more units\n"
6294 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6296 " list-dependencies [NAME] Recursively show units which are required\n"
6297 " or wanted by this unit or by which this\n"
6298 " unit is required or wanted\n\n"
6299 "Unit File Commands:\n"
6300 " list-unit-files [PATTERN...] List installed unit files\n"
6301 " enable NAME... Enable one or more unit files\n"
6302 " disable NAME... Disable one or more unit files\n"
6303 " reenable NAME... Reenable one or more unit files\n"
6304 " preset NAME... Enable/disable one or more unit files\n"
6305 " based on preset configuration\n"
6306 " preset-all Enable/disable all unit files based on\n"
6307 " preset configuration\n"
6308 " is-enabled NAME... Check whether unit files are enabled\n"
6309 " mask NAME... Mask one or more units\n"
6310 " unmask NAME... Unmask one or more units\n"
6311 " link PATH... Link one or more units files into\n"
6312 " the search path\n"
6313 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6314 " on specified one or more units\n"
6315 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6316 " on specified one or more units\n"
6317 " edit NAME... Edit one or more unit files\n"
6318 " get-default Get the name of the default target\n"
6319 " set-default NAME Set the default target\n\n"
6320 "Machine Commands:\n"
6321 " list-machines [PATTERN...] List local containers and host\n\n"
6323 " list-jobs [PATTERN...] List jobs\n"
6324 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6325 "Environment Commands:\n"
6326 " show-environment Dump environment\n"
6327 " set-environment NAME=VALUE... Set one or more environment variables\n"
6328 " unset-environment NAME... Unset one or more environment variables\n"
6329 " import-environment [NAME...] Import all or some environment variables\n\n"
6330 "Manager Lifecycle Commands:\n"
6331 " daemon-reload Reload systemd manager configuration\n"
6332 " daemon-reexec Reexecute systemd manager\n\n"
6333 "System Commands:\n"
6334 " is-system-running Check whether system is fully running\n"
6335 " default Enter system default mode\n"
6336 " rescue Enter system rescue mode\n"
6337 " emergency Enter system emergency mode\n"
6338 " halt Shut down and halt the system\n"
6339 " poweroff Shut down and power-off the system\n"
6340 " reboot [ARG] Shut down and reboot the system\n"
6341 " kexec Shut down and reboot the system with kexec\n"
6342 " exit [EXIT_CODE] Request user instance or container exit\n"
6343 " switch-root ROOT [INIT] Change to a different root file system\n"
6344 " suspend Suspend the system\n"
6345 " hibernate Hibernate the system\n"
6346 " hybrid-sleep Hibernate and suspend the system\n",
6347 program_invocation_short_name
);
6350 static void halt_help(void) {
6351 printf("%s [OPTIONS...]%s\n\n"
6352 "%s the system.\n\n"
6353 " --help Show this help\n"
6354 " --halt Halt the machine\n"
6355 " -p --poweroff Switch off the machine\n"
6356 " --reboot Reboot the machine\n"
6357 " -f --force Force immediate halt/power-off/reboot\n"
6358 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6359 " -d --no-wtmp Don't write wtmp record\n"
6360 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6361 program_invocation_short_name
,
6362 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6363 arg_action
== ACTION_REBOOT
? "Reboot" :
6364 arg_action
== ACTION_POWEROFF
? "Power off" :
6368 static void shutdown_help(void) {
6369 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6370 "Shut down the system.\n\n"
6371 " --help Show this help\n"
6372 " -H --halt Halt the machine\n"
6373 " -P --poweroff Power-off the machine\n"
6374 " -r --reboot Reboot the machine\n"
6375 " -h Equivalent to --poweroff, overridden by --halt\n"
6376 " -k Don't halt/power-off/reboot, just send warnings\n"
6377 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6378 " -c Cancel a pending shutdown\n",
6379 program_invocation_short_name
);
6382 static void telinit_help(void) {
6383 printf("%s [OPTIONS...] {COMMAND}\n\n"
6384 "Send control commands to the init daemon.\n\n"
6385 " --help Show this help\n"
6386 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6388 " 0 Power-off the machine\n"
6389 " 6 Reboot the machine\n"
6390 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6391 " 1, s, S Enter rescue mode\n"
6392 " q, Q Reload init daemon configuration\n"
6393 " u, U Reexecute init daemon\n",
6394 program_invocation_short_name
);
6397 static void runlevel_help(void) {
6398 printf("%s [OPTIONS...]\n\n"
6399 "Prints the previous and current runlevel of the init system.\n\n"
6400 " --help Show this help\n",
6401 program_invocation_short_name
);
6404 static void help_types(void) {
6408 puts("Available unit types:");
6409 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6410 puts(unit_type_to_string(i
));
6413 static void help_states(void) {
6417 puts("Available unit load states:");
6418 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6419 puts(unit_load_state_to_string(i
));
6422 puts("\nAvailable unit active states:");
6423 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6424 puts(unit_active_state_to_string(i
));
6427 puts("\nAvailable automount unit substates:");
6428 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6429 puts(automount_state_to_string(i
));
6432 puts("\nAvailable busname unit substates:");
6433 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6434 puts(busname_state_to_string(i
));
6437 puts("\nAvailable device unit substates:");
6438 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6439 puts(device_state_to_string(i
));
6442 puts("\nAvailable mount unit substates:");
6443 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6444 puts(mount_state_to_string(i
));
6447 puts("\nAvailable path unit substates:");
6448 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6449 puts(path_state_to_string(i
));
6452 puts("\nAvailable scope unit substates:");
6453 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6454 puts(scope_state_to_string(i
));
6457 puts("\nAvailable service unit substates:");
6458 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6459 puts(service_state_to_string(i
));
6462 puts("\nAvailable slice unit substates:");
6463 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6464 puts(slice_state_to_string(i
));
6467 puts("\nAvailable socket unit substates:");
6468 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6469 puts(socket_state_to_string(i
));
6472 puts("\nAvailable swap unit substates:");
6473 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6474 puts(swap_state_to_string(i
));
6477 puts("\nAvailable target unit substates:");
6478 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6479 puts(target_state_to_string(i
));
6482 puts("\nAvailable timer unit substates:");
6483 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6484 puts(timer_state_to_string(i
));
6487 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6496 ARG_IGNORE_DEPENDENCIES
,
6508 ARG_NO_ASK_PASSWORD
,
6521 static const struct option options
[] = {
6522 { "help", no_argument
, NULL
, 'h' },
6523 { "version", no_argument
, NULL
, ARG_VERSION
},
6524 { "type", required_argument
, NULL
, 't' },
6525 { "property", required_argument
, NULL
, 'p' },
6526 { "all", no_argument
, NULL
, 'a' },
6527 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6528 { "after", no_argument
, NULL
, ARG_AFTER
},
6529 { "before", no_argument
, NULL
, ARG_BEFORE
},
6530 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6531 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6532 { "full", no_argument
, NULL
, 'l' },
6533 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6534 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6535 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6536 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6537 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6538 { "user", no_argument
, NULL
, ARG_USER
},
6539 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6540 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6541 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6542 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6543 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6544 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6545 { "quiet", no_argument
, NULL
, 'q' },
6546 { "root", required_argument
, NULL
, ARG_ROOT
},
6547 { "force", no_argument
, NULL
, ARG_FORCE
},
6548 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6549 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6550 { "signal", required_argument
, NULL
, 's' },
6551 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6552 { "host", required_argument
, NULL
, 'H' },
6553 { "machine", required_argument
, NULL
, 'M' },
6554 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6555 { "lines", required_argument
, NULL
, 'n' },
6556 { "output", required_argument
, NULL
, 'o' },
6557 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6558 { "state", required_argument
, NULL
, ARG_STATE
},
6559 { "recursive", no_argument
, NULL
, 'r' },
6560 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6561 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6562 { "now", no_argument
, NULL
, ARG_NOW
},
6563 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6573 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6574 arg_ask_password
= true;
6576 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6588 if (isempty(optarg
)) {
6589 log_error("--type requires arguments.");
6595 _cleanup_free_
char *type
= NULL
;
6597 r
= extract_first_word(&p
, &type
, ",", 0);
6599 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6604 if (streq(type
, "help")) {
6609 if (unit_type_from_string(type
) >= 0) {
6610 if (strv_push(&arg_types
, type
) < 0)
6616 /* It's much nicer to use --state= for
6617 * load states, but let's support this
6618 * in --types= too for compatibility
6619 * with old versions */
6620 if (unit_load_state_from_string(type
) >= 0) {
6621 if (strv_push(&arg_states
, type
) < 0)
6627 log_error("Unknown unit type or load state '%s'.", type
);
6628 log_info("Use -t help to see a list of allowed values.");
6636 /* Make sure that if the empty property list
6637 was specified, we won't show any properties. */
6638 if (isempty(optarg
) && !arg_properties
) {
6639 arg_properties
= new0(char*, 1);
6640 if (!arg_properties
)
6645 _cleanup_free_
char *prop
= NULL
;
6647 r
= extract_first_word(&p
, &prop
, ",", 0);
6649 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6654 if (strv_push(&arg_properties
, prop
) < 0)
6661 /* If the user asked for a particular
6662 * property, show it to him, even if it is
6674 arg_dependency
= DEPENDENCY_REVERSE
;
6678 arg_dependency
= DEPENDENCY_AFTER
;
6682 arg_dependency
= DEPENDENCY_BEFORE
;
6685 case ARG_SHOW_TYPES
:
6686 arg_show_types
= true;
6690 arg_job_mode
= optarg
;
6694 arg_job_mode
= "fail";
6697 case ARG_IRREVERSIBLE
:
6698 arg_job_mode
= "replace-irreversibly";
6701 case ARG_IGNORE_DEPENDENCIES
:
6702 arg_job_mode
= "ignore-dependencies";
6706 arg_scope
= UNIT_FILE_USER
;
6710 arg_scope
= UNIT_FILE_SYSTEM
;
6714 arg_scope
= UNIT_FILE_GLOBAL
;
6718 arg_no_block
= true;
6722 arg_no_legend
= true;
6726 arg_no_pager
= true;
6734 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6744 if (strv_extend(&arg_states
, "failed") < 0)
6762 arg_no_reload
= true;
6766 arg_kill_who
= optarg
;
6770 arg_signal
= signal_from_string_try_harder(optarg
);
6771 if (arg_signal
< 0) {
6772 log_error("Failed to parse signal string %s.", optarg
);
6777 case ARG_NO_ASK_PASSWORD
:
6778 arg_ask_password
= false;
6782 arg_transport
= BUS_TRANSPORT_REMOTE
;
6787 arg_transport
= BUS_TRANSPORT_MACHINE
;
6796 if (safe_atou(optarg
, &arg_lines
) < 0) {
6797 log_error("Failed to parse lines '%s'", optarg
);
6803 arg_output
= output_mode_from_string(optarg
);
6804 if (arg_output
< 0) {
6805 log_error("Unknown output '%s'.", optarg
);
6811 arg_ignore_inhibitors
= true;
6818 case ARG_FIRMWARE_SETUP
:
6819 arg_firmware_setup
= true;
6823 if (isempty(optarg
)) {
6824 log_error("--signal requires arguments.");
6830 _cleanup_free_
char *s
= NULL
;
6832 r
= extract_first_word(&p
, &s
, ",", 0);
6834 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6839 if (streq(s
, "help")) {
6844 if (strv_push(&arg_states
, s
) < 0)
6853 if (geteuid() != 0) {
6854 log_error("--recursive requires root privileges.");
6858 arg_recursive
= true;
6861 case ARG_PRESET_MODE
:
6863 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6864 if (arg_preset_mode
< 0) {
6865 log_error("Failed to parse preset mode: %s.", optarg
);
6876 if (strv_extend(&arg_wall
, optarg
) < 0)
6884 assert_not_reached("Unhandled option");
6887 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6888 log_error("Cannot access user instance remotely.");
6895 static int halt_parse_argv(int argc
, char *argv
[]) {
6904 static const struct option options
[] = {
6905 { "help", no_argument
, NULL
, ARG_HELP
},
6906 { "halt", no_argument
, NULL
, ARG_HALT
},
6907 { "poweroff", no_argument
, NULL
, 'p' },
6908 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6909 { "force", no_argument
, NULL
, 'f' },
6910 { "wtmp-only", no_argument
, NULL
, 'w' },
6911 { "no-wtmp", no_argument
, NULL
, 'd' },
6912 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6921 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6922 if (runlevel
== '0' || runlevel
== '6')
6925 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6933 arg_action
= ACTION_HALT
;
6937 if (arg_action
!= ACTION_REBOOT
)
6938 arg_action
= ACTION_POWEROFF
;
6942 arg_action
= ACTION_REBOOT
;
6964 /* Compatibility nops */
6971 assert_not_reached("Unhandled option");
6974 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6975 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6978 } else if (optind
< argc
) {
6979 log_error("Too many arguments.");
6986 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
6990 if (streq(t
, "now"))
6992 else if (!strchr(t
, ':')) {
6995 if (safe_atou64(t
, &u
) < 0)
6998 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7007 hour
= strtol(t
, &e
, 10);
7008 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7011 minute
= strtol(e
+1, &e
, 10);
7012 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7015 n
= now(CLOCK_REALTIME
);
7016 s
= (time_t) (n
/ USEC_PER_SEC
);
7018 assert_se(localtime_r(&s
, &tm
));
7020 tm
.tm_hour
= (int) hour
;
7021 tm
.tm_min
= (int) minute
;
7024 assert_se(s
= mktime(&tm
));
7026 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7029 *_u
+= USEC_PER_DAY
;
7035 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7042 static const struct option options
[] = {
7043 { "help", no_argument
, NULL
, ARG_HELP
},
7044 { "halt", no_argument
, NULL
, 'H' },
7045 { "poweroff", no_argument
, NULL
, 'P' },
7046 { "reboot", no_argument
, NULL
, 'r' },
7047 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7048 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7058 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7066 arg_action
= ACTION_HALT
;
7070 arg_action
= ACTION_POWEROFF
;
7075 arg_action
= ACTION_KEXEC
;
7077 arg_action
= ACTION_REBOOT
;
7081 arg_action
= ACTION_KEXEC
;
7085 if (arg_action
!= ACTION_HALT
)
7086 arg_action
= ACTION_POWEROFF
;
7101 /* Compatibility nops */
7105 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7112 assert_not_reached("Unhandled option");
7115 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7116 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7118 log_error("Failed to parse time specification: %s", argv
[optind
]);
7122 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7124 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7125 /* No time argument for shutdown cancel */
7126 wall
= argv
+ optind
;
7127 else if (argc
> optind
+ 1)
7128 /* We skip the time argument */
7129 wall
= argv
+ optind
+ 1;
7132 arg_wall
= strv_copy(wall
);
7142 static int telinit_parse_argv(int argc
, char *argv
[]) {
7149 static const struct option options
[] = {
7150 { "help", no_argument
, NULL
, ARG_HELP
},
7151 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7155 static const struct {
7159 { '0', ACTION_POWEROFF
},
7160 { '6', ACTION_REBOOT
},
7161 { '1', ACTION_RESCUE
},
7162 { '2', ACTION_RUNLEVEL2
},
7163 { '3', ACTION_RUNLEVEL3
},
7164 { '4', ACTION_RUNLEVEL4
},
7165 { '5', ACTION_RUNLEVEL5
},
7166 { 's', ACTION_RESCUE
},
7167 { 'S', ACTION_RESCUE
},
7168 { 'q', ACTION_RELOAD
},
7169 { 'Q', ACTION_RELOAD
},
7170 { 'u', ACTION_REEXEC
},
7171 { 'U', ACTION_REEXEC
}
7180 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7195 assert_not_reached("Unhandled option");
7198 if (optind
>= argc
) {
7199 log_error("%s: required argument missing.", program_invocation_short_name
);
7203 if (optind
+ 1 < argc
) {
7204 log_error("Too many arguments.");
7208 if (strlen(argv
[optind
]) != 1) {
7209 log_error("Expected single character argument.");
7213 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7214 if (table
[i
].from
== argv
[optind
][0])
7217 if (i
>= ELEMENTSOF(table
)) {
7218 log_error("Unknown command '%s'.", argv
[optind
]);
7222 arg_action
= table
[i
].to
;
7229 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7235 static const struct option options
[] = {
7236 { "help", no_argument
, NULL
, ARG_HELP
},
7245 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7256 assert_not_reached("Unhandled option");
7259 if (optind
< argc
) {
7260 log_error("Too many arguments.");
7267 static int parse_argv(int argc
, char *argv
[]) {
7271 if (program_invocation_short_name
) {
7273 if (strstr(program_invocation_short_name
, "halt")) {
7274 arg_action
= ACTION_HALT
;
7275 return halt_parse_argv(argc
, argv
);
7276 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7277 arg_action
= ACTION_POWEROFF
;
7278 return halt_parse_argv(argc
, argv
);
7279 } else if (strstr(program_invocation_short_name
, "reboot")) {
7281 arg_action
= ACTION_KEXEC
;
7283 arg_action
= ACTION_REBOOT
;
7284 return halt_parse_argv(argc
, argv
);
7285 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7286 arg_action
= ACTION_POWEROFF
;
7287 return shutdown_parse_argv(argc
, argv
);
7288 } else if (strstr(program_invocation_short_name
, "init")) {
7290 if (sd_booted() > 0) {
7291 arg_action
= _ACTION_INVALID
;
7292 return telinit_parse_argv(argc
, argv
);
7294 /* Hmm, so some other init system is
7295 * running, we need to forward this
7296 * request to it. For now we simply
7297 * guess that it is Upstart. */
7299 execv(TELINIT
, argv
);
7301 log_error("Couldn't find an alternative telinit implementation to spawn.");
7305 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7306 arg_action
= ACTION_RUNLEVEL
;
7307 return runlevel_parse_argv(argc
, argv
);
7311 arg_action
= ACTION_SYSTEMCTL
;
7312 return systemctl_parse_argv(argc
, argv
);
7315 #ifdef HAVE_SYSV_COMPAT
7316 _pure_
static int action_to_runlevel(void) {
7318 static const char table
[_ACTION_MAX
] = {
7319 [ACTION_HALT
] = '0',
7320 [ACTION_POWEROFF
] = '0',
7321 [ACTION_REBOOT
] = '6',
7322 [ACTION_RUNLEVEL2
] = '2',
7323 [ACTION_RUNLEVEL3
] = '3',
7324 [ACTION_RUNLEVEL4
] = '4',
7325 [ACTION_RUNLEVEL5
] = '5',
7326 [ACTION_RESCUE
] = '1'
7329 assert(arg_action
< _ACTION_MAX
);
7331 return table
[arg_action
];
7335 static int talk_initctl(void) {
7336 #ifdef HAVE_SYSV_COMPAT
7337 struct init_request request
= {
7338 .magic
= INIT_MAGIC
,
7340 .cmd
= INIT_CMD_RUNLVL
7343 _cleanup_close_
int fd
= -1;
7347 rl
= action_to_runlevel();
7351 request
.runlevel
= rl
;
7353 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7355 if (errno
== ENOENT
)
7358 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7361 r
= loop_write(fd
, &request
, sizeof(request
), false);
7363 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7371 static int systemctl_main(int argc
, char *argv
[]) {
7373 static const Verb verbs
[] = {
7374 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7375 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7376 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7377 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7378 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7379 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7380 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7381 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7382 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7383 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7384 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7385 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7386 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7387 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7388 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7389 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7390 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7391 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7392 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7393 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7394 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7395 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7396 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7397 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7398 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7399 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7400 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7401 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7402 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7403 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7404 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7405 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7406 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7407 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7408 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7409 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7410 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7411 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7412 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7413 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7414 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7415 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7416 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7417 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7418 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7419 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7420 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7421 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7422 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7423 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7424 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7425 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7426 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7427 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7428 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7429 { "link", 2, VERB_ANY
, 0, enable_unit
},
7430 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7431 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7432 { "set-default", 2, 2, 0, set_default
},
7433 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7434 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7435 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7436 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7437 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7438 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7442 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7445 static int reload_with_fallback(void) {
7447 /* First, try systemd via D-Bus. */
7448 if (daemon_reload(0, NULL
, NULL
) >= 0)
7451 /* Nothing else worked, so let's try signals */
7452 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7454 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7455 return log_error_errno(errno
, "kill() failed: %m");
7460 static int start_with_fallback(void) {
7462 /* First, try systemd via D-Bus. */
7463 if (start_unit(0, NULL
, NULL
) >= 0)
7466 /* Nothing else worked, so let's try
7468 if (talk_initctl() > 0)
7471 log_error("Failed to talk to init daemon.");
7475 static int halt_now(enum action a
) {
7477 /* The kernel will automaticall flush ATA disks and suchlike
7478 * on reboot(), but the file systems need to be synce'd
7479 * explicitly in advance. */
7482 /* Make sure C-A-D is handled by the kernel from this point
7484 (void) reboot(RB_ENABLE_CAD
);
7489 log_info("Halting.");
7490 (void) reboot(RB_HALT_SYSTEM
);
7493 case ACTION_POWEROFF
:
7494 log_info("Powering off.");
7495 (void) reboot(RB_POWER_OFF
);
7499 case ACTION_REBOOT
: {
7500 _cleanup_free_
char *param
= NULL
;
7502 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7503 log_info("Rebooting with argument '%s'.", param
);
7504 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7507 log_info("Rebooting.");
7508 (void) reboot(RB_AUTOBOOT
);
7513 assert_not_reached("Unknown action.");
7517 static int logind_schedule_shutdown(void) {
7520 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7521 char date
[FORMAT_TIMESTAMP_MAX
];
7526 (void) logind_set_wall_message();
7528 r
= acquire_bus(BUS_FULL
, &bus
);
7532 switch (arg_action
) {
7536 case ACTION_POWEROFF
:
7537 action
= "poweroff";
7552 action
= strjoina("dry-", action
);
7554 r
= sd_bus_call_method(
7556 "org.freedesktop.login1",
7557 "/org/freedesktop/login1",
7558 "org.freedesktop.login1.Manager",
7566 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7568 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7571 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7576 static int halt_main(void) {
7579 r
= logind_check_inhibitors(arg_action
);
7584 return logind_schedule_shutdown();
7586 if (geteuid() != 0) {
7587 if (arg_dry
|| arg_force
> 0) {
7588 log_error("Must be root.");
7592 /* Try logind if we are a normal user and no special
7593 * mode applies. Maybe PolicyKit allows us to shutdown
7595 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7596 r
= logind_reboot(arg_action
);
7599 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7600 /* requested operation is not
7601 * supported on the local system or
7602 * already in progress */
7604 /* on all other errors, try low-level operation */
7608 if (!arg_dry
&& !arg_force
)
7609 return start_with_fallback();
7611 assert(geteuid() == 0);
7614 if (sd_booted() > 0)
7615 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7617 r
= utmp_put_shutdown();
7619 log_warning_errno(r
, "Failed to write utmp record: %m");
7626 r
= halt_now(arg_action
);
7627 return log_error_errno(r
, "Failed to reboot: %m");
7630 static int runlevel_main(void) {
7631 int r
, runlevel
, previous
;
7633 r
= utmp_get_runlevel(&runlevel
, &previous
);
7640 previous
<= 0 ? 'N' : previous
,
7641 runlevel
<= 0 ? 'N' : runlevel
);
7646 static int logind_cancel_shutdown(void) {
7648 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7652 r
= acquire_bus(BUS_FULL
, &bus
);
7656 (void) logind_set_wall_message();
7658 r
= sd_bus_call_method(
7660 "org.freedesktop.login1",
7661 "/org/freedesktop/login1",
7662 "org.freedesktop.login1.Manager",
7663 "CancelScheduledShutdown",
7667 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7671 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7676 int main(int argc
, char*argv
[]) {
7679 setlocale(LC_ALL
, "");
7680 log_parse_environment();
7683 /* Explicitly not on_tty() to avoid setting cached value.
7684 * This becomes relevant for piping output which might be
7686 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7688 r
= parse_argv(argc
, argv
);
7692 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7693 log_info("Running in chroot, ignoring request.");
7698 /* systemctl_main() will print an error message for the bus
7699 * connection, but only if it needs to */
7701 switch (arg_action
) {
7703 case ACTION_SYSTEMCTL
:
7704 r
= systemctl_main(argc
, argv
);
7708 case ACTION_POWEROFF
:
7714 case ACTION_RUNLEVEL2
:
7715 case ACTION_RUNLEVEL3
:
7716 case ACTION_RUNLEVEL4
:
7717 case ACTION_RUNLEVEL5
:
7719 case ACTION_EMERGENCY
:
7720 case ACTION_DEFAULT
:
7721 r
= start_with_fallback();
7726 r
= reload_with_fallback();
7729 case ACTION_CANCEL_SHUTDOWN
:
7730 r
= logind_cancel_shutdown();
7733 case ACTION_RUNLEVEL
:
7734 r
= runlevel_main();
7737 case _ACTION_INVALID
:
7739 assert_not_reached("Unknown action");
7744 ask_password_agent_close();
7745 polkit_agent_close();
7747 strv_free(arg_types
);
7748 strv_free(arg_states
);
7749 strv_free(arg_properties
);
7751 strv_free(arg_wall
);
7756 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7758 return r
< 0 ? EXIT_FAILURE
: r
;