1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <linux/reboot.h>
32 #include <sys/reboot.h>
33 #include <sys/socket.h>
37 #include "sd-daemon.h"
41 #include "bus-common-errors.h"
42 #include "bus-error.h"
43 #include "bus-message.h"
45 #include "cgroup-show.h"
46 #include "cgroup-util.h"
51 #include "exit-status.h"
53 #include "formats-util.h"
54 #include "hostname-util.h"
59 #include "logs-show.h"
63 #include "path-lookup.h"
64 #include "path-util.h"
65 #include "process-util.h"
67 #include "signal-util.h"
68 #include "socket-util.h"
69 #include "spawn-ask-password-agent.h"
70 #include "spawn-polkit-agent.h"
73 #include "terminal-util.h"
74 #include "unit-name.h"
76 #include "utmp-wtmp.h"
78 static char **arg_types
= NULL
;
79 static char **arg_states
= NULL
;
80 static char **arg_properties
= NULL
;
81 static bool arg_all
= false;
82 static enum dependency
{
88 } arg_dependency
= DEPENDENCY_FORWARD
;
89 static const char *arg_job_mode
= "replace";
90 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
91 static bool arg_no_block
= false;
92 static bool arg_no_legend
= false;
93 static bool arg_no_pager
= false;
94 static bool arg_no_wtmp
= false;
95 static bool arg_no_wall
= false;
96 static bool arg_no_reload
= false;
97 static bool arg_show_types
= false;
98 static bool arg_ignore_inhibitors
= false;
99 static bool arg_dry
= false;
100 static bool arg_quiet
= false;
101 static bool arg_full
= false;
102 static bool arg_recursive
= false;
103 static int arg_force
= 0;
104 static bool arg_ask_password
= false;
105 static bool arg_runtime
= false;
106 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
107 static char **arg_wall
= NULL
;
108 static const char *arg_kill_who
= NULL
;
109 static int arg_signal
= SIGTERM
;
110 static const char *arg_root
= NULL
;
111 static usec_t arg_when
= 0;
133 ACTION_CANCEL_SHUTDOWN
,
135 } arg_action
= ACTION_SYSTEMCTL
;
136 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
137 static char *arg_host
= NULL
;
138 static unsigned arg_lines
= 10;
139 static OutputMode arg_output
= OUTPUT_SHORT
;
140 static bool arg_plain
= false;
141 static bool arg_firmware_setup
= false;
142 static bool arg_now
= false;
144 static bool original_stdout_is_tty
;
146 static int daemon_reload(sd_bus
*bus
, char **args
);
147 static int halt_now(enum action a
);
148 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
150 static char** strv_skip_first(char **strv
) {
151 if (strv_length(strv
) > 0)
156 static void pager_open_if_enabled(void) {
164 static void ask_password_agent_open_if_enabled(void) {
166 /* Open the password agent as a child process if necessary */
168 if (!arg_ask_password
)
171 if (arg_scope
!= UNIT_FILE_SYSTEM
)
174 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
177 ask_password_agent_open();
180 static void polkit_agent_open_if_enabled(void) {
182 /* Open the polkit agent as a child process if necessary */
184 if (!arg_ask_password
)
187 if (arg_scope
!= UNIT_FILE_SYSTEM
)
190 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
196 static OutputFlags
get_output_flags(void) {
198 arg_all
* OUTPUT_SHOW_ALL
|
199 arg_full
* OUTPUT_FULL_WIDTH
|
200 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
201 on_tty() * OUTPUT_COLOR
|
202 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
205 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
208 if (!sd_bus_error_is_set(error
))
211 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
212 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
213 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
214 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
215 return EXIT_NOPERMISSION
;
217 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
218 return EXIT_NOTINSTALLED
;
220 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
221 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
222 return EXIT_NOTIMPLEMENTED
;
224 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
225 return EXIT_NOTCONFIGURED
;
233 static void warn_wall(enum action a
) {
234 static const char *table
[_ACTION_MAX
] = {
235 [ACTION_HALT
] = "The system is going down for system halt NOW!",
236 [ACTION_REBOOT
] = "The system is going down for reboot NOW!",
237 [ACTION_POWEROFF
] = "The system is going down for power-off NOW!",
238 [ACTION_KEXEC
] = "The system is going down for kexec reboot NOW!",
239 [ACTION_RESCUE
] = "The system is going down to rescue mode NOW!",
240 [ACTION_EMERGENCY
] = "The system is going down to emergency mode NOW!",
241 [ACTION_CANCEL_SHUTDOWN
] = "The system shutdown has been cancelled NOW!"
248 _cleanup_free_
char *p
;
250 p
= strv_join(arg_wall
, " ");
257 utmp_wall(p
, NULL
, NULL
, NULL
, NULL
);
265 utmp_wall(table
[a
], NULL
, NULL
, NULL
, NULL
);
268 static bool avoid_bus(void) {
270 if (running_in_chroot() > 0)
273 if (sd_booted() <= 0)
276 if (!isempty(arg_root
))
279 if (arg_scope
== UNIT_FILE_GLOBAL
)
285 static int compare_unit_info(const void *a
, const void *b
) {
286 const UnitInfo
*u
= a
, *v
= b
;
290 /* First, order by machine */
291 if (!u
->machine
&& v
->machine
)
293 if (u
->machine
&& !v
->machine
)
295 if (u
->machine
&& v
->machine
) {
296 r
= strcasecmp(u
->machine
, v
->machine
);
301 /* Second, order by unit type */
302 d1
= strrchr(u
->id
, '.');
303 d2
= strrchr(v
->id
, '.');
305 r
= strcasecmp(d1
, d2
);
310 /* Third, order by name */
311 return strcasecmp(u
->id
, v
->id
);
314 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
315 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
321 dot
= strrchr(u
->id
, '.');
325 if (!strv_find(arg_types
, dot
+1))
335 if (streq(u
->active_state
, "inactive") || u
->following
[0])
341 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
342 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
344 unsigned n_shown
= 0;
347 max_id_len
= strlen("UNIT");
348 load_len
= strlen("LOAD");
349 active_len
= strlen("ACTIVE");
350 sub_len
= strlen("SUB");
351 job_len
= strlen("JOB");
354 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
355 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
356 load_len
= MAX(load_len
, strlen(u
->load_state
));
357 active_len
= MAX(active_len
, strlen(u
->active_state
));
358 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
360 if (u
->job_id
!= 0) {
361 job_len
= MAX(job_len
, strlen(u
->job_type
));
365 if (!arg_no_legend
&&
366 (streq(u
->active_state
, "failed") ||
367 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
371 if (!arg_full
&& original_stdout_is_tty
) {
374 id_len
= MIN(max_id_len
, 25u);
375 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
378 basic_len
+= job_len
+ 1;
380 if (basic_len
< (unsigned) columns()) {
381 unsigned extra_len
, incr
;
382 extra_len
= columns() - basic_len
;
384 /* Either UNIT already got 25, or is fully satisfied.
385 * Grant up to 25 to DESC now. */
386 incr
= MIN(extra_len
, 25u);
390 /* split the remaining space between UNIT and DESC,
391 * but do not give UNIT more than it needs. */
393 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
395 desc_len
+= extra_len
- incr
;
401 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
402 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
403 const char *on_loaded
= "", *off_loaded
= "";
404 const char *on_active
= "", *off_active
= "";
405 const char *on_circle
= "", *off_circle
= "";
409 if (!n_shown
&& !arg_no_legend
) {
414 printf("%-*s %-*s %-*s %-*s ",
417 active_len
, "ACTIVE",
421 printf("%-*s ", job_len
, "JOB");
423 if (!arg_full
&& arg_no_pager
)
424 printf("%.*s\n", desc_len
, "DESCRIPTION");
426 printf("%s\n", "DESCRIPTION");
431 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
432 on_loaded
= ansi_highlight_red();
433 on_circle
= ansi_highlight_yellow();
434 off_loaded
= off_circle
= ansi_normal();
436 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
437 on_circle
= on_active
= ansi_highlight_red();
438 off_circle
= off_active
= ansi_normal();
443 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
452 e
= ellipsize(id
, id_len
, 33);
460 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
462 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
463 on_active
, id_len
, id
, off_active
,
464 on_loaded
, load_len
, u
->load_state
, off_loaded
,
465 on_active
, active_len
, u
->active_state
,
466 sub_len
, u
->sub_state
, off_active
,
467 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
470 printf("%.*s\n", desc_len
, u
->description
);
472 printf("%s\n", u
->description
);
475 if (!arg_no_legend
) {
476 const char *on
, *off
;
480 "LOAD = Reflects whether the unit definition was properly loaded.\n"
481 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
482 "SUB = The low-level unit activation state, values depend on unit type.");
483 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
484 on
= ansi_highlight();
487 on
= ansi_highlight_red();
492 printf("%s%u loaded units listed.%s\n"
493 "To show all installed unit files use 'systemctl list-unit-files'.\n",
496 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
497 "To show all installed unit files use 'systemctl list-unit-files'.\n",
504 static int get_unit_list(
508 UnitInfo
**unit_infos
,
510 sd_bus_message
**_reply
) {
512 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
513 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
514 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
523 r
= sd_bus_message_new_method_call(
526 "org.freedesktop.systemd1",
527 "/org/freedesktop/systemd1",
528 "org.freedesktop.systemd1.Manager",
529 "ListUnitsFiltered");
532 return bus_log_create_error(r
);
534 r
= sd_bus_message_append_strv(m
, arg_states
);
536 return bus_log_create_error(r
);
538 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
540 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
542 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
544 return bus_log_parse_error(r
);
546 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
549 if (!output_show_unit(&u
, patterns
))
552 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
555 (*unit_infos
)[c
++] = u
;
558 return bus_log_parse_error(r
);
560 r
= sd_bus_message_exit_container(reply
);
562 return bus_log_parse_error(r
);
570 static void message_set_freep(Set
**set
) {
573 while ((m
= set_steal_first(*set
)))
574 sd_bus_message_unref(m
);
579 static int get_unit_list_recursive(
582 UnitInfo
**_unit_infos
,
586 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
587 _cleanup_(message_set_freep
) Set
*replies
;
588 sd_bus_message
*reply
;
596 replies
= set_new(NULL
);
600 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
604 r
= set_put(replies
, reply
);
606 sd_bus_message_unref(reply
);
611 _cleanup_strv_free_
char **machines
= NULL
;
614 r
= sd_get_machine_names(&machines
);
616 return log_error_errno(r
, "Failed to get machine names: %m");
618 STRV_FOREACH(i
, machines
) {
619 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
622 r
= sd_bus_open_system_machine(&container
, *i
);
624 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
628 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
634 r
= set_put(replies
, reply
);
636 sd_bus_message_unref(reply
);
641 *_machines
= machines
;
646 *_unit_infos
= unit_infos
;
655 static int list_units(sd_bus
*bus
, char **args
) {
656 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
657 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
658 _cleanup_strv_free_
char **machines
= NULL
;
661 pager_open_if_enabled();
663 r
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
667 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
668 return output_units_list(unit_infos
, r
);
671 static int get_triggered_units(
676 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
679 r
= sd_bus_get_property_strv(
681 "org.freedesktop.systemd1",
683 "org.freedesktop.systemd1.Unit",
689 log_error("Failed to determine triggers: %s", bus_error_message(&error
, r
));
694 static int get_listening(
696 const char* unit_path
,
699 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
700 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
701 const char *type
, *path
;
704 r
= sd_bus_get_property(
706 "org.freedesktop.systemd1",
708 "org.freedesktop.systemd1.Socket",
714 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
718 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
720 return bus_log_parse_error(r
);
722 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
724 r
= strv_extend(listening
, type
);
728 r
= strv_extend(listening
, path
);
735 return bus_log_parse_error(r
);
737 r
= sd_bus_message_exit_container(reply
);
739 return bus_log_parse_error(r
);
751 /* Note: triggered is a list here, although it almost certainly
752 * will always be one unit. Nevertheless, dbus API allows for multiple
753 * values, so let's follow that. */
756 /* The strv above is shared. free is set only in the first one. */
760 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
766 if (!a
->machine
&& b
->machine
)
768 if (a
->machine
&& !b
->machine
)
770 if (a
->machine
&& b
->machine
) {
771 o
= strcasecmp(a
->machine
, b
->machine
);
776 o
= strcmp(a
->path
, b
->path
);
778 o
= strcmp(a
->type
, b
->type
);
783 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
784 struct socket_info
*s
;
785 unsigned pathlen
= strlen("LISTEN"),
786 typelen
= strlen("TYPE") * arg_show_types
,
787 socklen
= strlen("UNIT"),
788 servlen
= strlen("ACTIVATES");
789 const char *on
, *off
;
791 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
795 socklen
= MAX(socklen
, strlen(s
->id
));
797 typelen
= MAX(typelen
, strlen(s
->type
));
798 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
800 STRV_FOREACH(a
, s
->triggered
)
801 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
802 servlen
= MAX(servlen
, tmp
);
807 printf("%-*s %-*.*s%-*s %s\n",
809 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
813 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
814 _cleanup_free_
char *j
= NULL
;
819 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
827 printf("%-*s %-*s %-*s",
828 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
831 pathlen
, path
, socklen
, s
->id
);
832 STRV_FOREACH(a
, s
->triggered
)
834 a
== s
->triggered
? "" : ",", *a
);
838 on
= ansi_highlight();
843 on
= ansi_highlight_red();
847 if (!arg_no_legend
) {
848 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
850 printf("Pass --all to see loaded but inactive sockets, too.\n");
856 static int list_sockets(sd_bus
*bus
, char **args
) {
857 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
858 _cleanup_strv_free_
char **machines
= NULL
;
859 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
860 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
862 struct socket_info
*s
;
867 pager_open_if_enabled();
869 n
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
873 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
874 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
877 if (!endswith(u
->id
, ".socket"))
880 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
884 c
= get_listening(bus
, u
->unit_path
, &listening
);
890 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
895 for (i
= 0; i
< c
; i
++)
896 socket_infos
[cs
+ i
] = (struct socket_info
) {
897 .machine
= u
->machine
,
899 .type
= listening
[i
*2],
900 .path
= listening
[i
*2 + 1],
901 .triggered
= triggered
,
902 .own_triggered
= i
==0,
905 /* from this point on we will cleanup those socket_infos */
908 listening
= triggered
= NULL
; /* avoid cleanup */
911 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
912 (__compar_fn_t
) socket_info_compare
);
914 output_sockets_list(socket_infos
, cs
);
917 assert(cs
== 0 || socket_infos
);
918 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
921 if (s
->own_triggered
)
922 strv_free(s
->triggered
);
928 static int get_next_elapse(
931 dual_timestamp
*next
) {
933 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
941 r
= sd_bus_get_property_trivial(
943 "org.freedesktop.systemd1",
945 "org.freedesktop.systemd1.Timer",
946 "NextElapseUSecMonotonic",
951 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
955 r
= sd_bus_get_property_trivial(
957 "org.freedesktop.systemd1",
959 "org.freedesktop.systemd1.Timer",
960 "NextElapseUSecRealtime",
965 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
973 static int get_last_trigger(
978 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
985 r
= sd_bus_get_property_trivial(
987 "org.freedesktop.systemd1",
989 "org.freedesktop.systemd1.Timer",
995 log_error("Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1003 const char* machine
;
1006 usec_t last_trigger
;
1010 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1016 if (!a
->machine
&& b
->machine
)
1018 if (a
->machine
&& !b
->machine
)
1020 if (a
->machine
&& b
->machine
) {
1021 o
= strcasecmp(a
->machine
, b
->machine
);
1026 if (a
->next_elapse
< b
->next_elapse
)
1028 if (a
->next_elapse
> b
->next_elapse
)
1031 return strcmp(a
->id
, b
->id
);
1034 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1035 struct timer_info
*t
;
1037 nextlen
= strlen("NEXT"),
1038 leftlen
= strlen("LEFT"),
1039 lastlen
= strlen("LAST"),
1040 passedlen
= strlen("PASSED"),
1041 unitlen
= strlen("UNIT"),
1042 activatelen
= strlen("ACTIVATES");
1044 const char *on
, *off
;
1046 assert(timer_infos
|| n
== 0);
1048 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1052 if (t
->next_elapse
> 0) {
1053 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1055 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1056 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1058 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1059 leftlen
= MAX(leftlen
, strlen(trel
));
1062 if (t
->last_trigger
> 0) {
1063 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1065 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1066 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1068 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1069 passedlen
= MAX(passedlen
, strlen(trel
));
1072 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1074 STRV_FOREACH(a
, t
->triggered
)
1075 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1077 activatelen
= MAX(activatelen
, ul
);
1082 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1086 passedlen
, "PASSED",
1090 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1091 _cleanup_free_
char *j
= NULL
;
1093 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1094 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1097 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1098 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1100 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1101 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1104 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1111 printf("%-*s %-*s %-*s %-*s %-*s",
1112 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1114 STRV_FOREACH(a
, t
->triggered
)
1116 a
== t
->triggered
? "" : ",", *a
);
1120 on
= ansi_highlight();
1121 off
= ansi_normal();
1125 on
= ansi_highlight_red();
1126 off
= ansi_normal();
1129 if (!arg_no_legend
) {
1130 printf("%s%u timers listed.%s\n", on
, n
, off
);
1132 printf("Pass --all to see loaded but inactive timers, too.\n");
1138 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1144 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1147 if (next
->monotonic
> nw
->monotonic
)
1148 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1150 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1152 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1153 next_elapse
= MIN(converted
, next
->realtime
);
1155 next_elapse
= converted
;
1158 next_elapse
= next
->realtime
;
1163 static int list_timers(sd_bus
*bus
, char **args
) {
1164 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1165 _cleanup_strv_free_
char **machines
= NULL
;
1166 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1167 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1168 struct timer_info
*t
;
1175 pager_open_if_enabled();
1177 n
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
1181 dual_timestamp_get(&nw
);
1183 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1184 _cleanup_strv_free_
char **triggered
= NULL
;
1185 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1188 if (!endswith(u
->id
, ".timer"))
1191 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1195 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1199 get_last_trigger(bus
, u
->unit_path
, &last
);
1201 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1206 m
= calc_next_elapse(&nw
, &next
);
1208 timer_infos
[c
++] = (struct timer_info
) {
1209 .machine
= u
->machine
,
1212 .last_trigger
= last
,
1213 .triggered
= triggered
,
1216 triggered
= NULL
; /* avoid cleanup */
1219 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1220 (__compar_fn_t
) timer_info_compare
);
1222 output_timers_list(timer_infos
, c
);
1225 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1226 strv_free(t
->triggered
);
1231 static int compare_unit_file_list(const void *a
, const void *b
) {
1232 const char *d1
, *d2
;
1233 const UnitFileList
*u
= a
, *v
= b
;
1235 d1
= strrchr(u
->path
, '.');
1236 d2
= strrchr(v
->path
, '.');
1241 r
= strcasecmp(d1
, d2
);
1246 return strcasecmp(basename(u
->path
), basename(v
->path
));
1249 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1250 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1253 if (!strv_isempty(arg_types
)) {
1256 dot
= strrchr(u
->path
, '.');
1260 if (!strv_find(arg_types
, dot
+1))
1264 if (!strv_isempty(arg_states
) &&
1265 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1271 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1272 unsigned max_id_len
, id_cols
, state_cols
;
1273 const UnitFileList
*u
;
1275 max_id_len
= strlen("UNIT FILE");
1276 state_cols
= strlen("STATE");
1278 for (u
= units
; u
< units
+ c
; u
++) {
1279 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1280 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1284 unsigned basic_cols
;
1286 id_cols
= MIN(max_id_len
, 25u);
1287 basic_cols
= 1 + id_cols
+ state_cols
;
1288 if (basic_cols
< (unsigned) columns())
1289 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1291 id_cols
= max_id_len
;
1294 printf("%-*s %-*s\n",
1295 id_cols
, "UNIT FILE",
1296 state_cols
, "STATE");
1298 for (u
= units
; u
< units
+ c
; u
++) {
1299 _cleanup_free_
char *e
= NULL
;
1300 const char *on
, *off
;
1303 if (IN_SET(u
->state
,
1305 UNIT_FILE_MASKED_RUNTIME
,
1307 UNIT_FILE_INVALID
)) {
1308 on
= ansi_highlight_red();
1309 off
= ansi_normal();
1310 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1311 on
= ansi_highlight_green();
1312 off
= ansi_normal();
1316 id
= basename(u
->path
);
1318 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1320 printf("%-*s %s%-*s%s\n",
1321 id_cols
, e
? e
: id
,
1322 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1326 printf("\n%u unit files listed.\n", c
);
1329 static int list_unit_files(sd_bus
*bus
, char **args
) {
1330 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1331 _cleanup_free_ UnitFileList
*units
= NULL
;
1339 pager_open_if_enabled();
1347 h
= hashmap_new(&string_hash_ops
);
1351 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1353 unit_file_list_free(h
);
1354 log_error_errno(r
, "Failed to get unit file list: %m");
1358 n_units
= hashmap_size(h
);
1360 units
= new(UnitFileList
, n_units
);
1361 if (!units
&& n_units
> 0) {
1362 unit_file_list_free(h
);
1366 HASHMAP_FOREACH(u
, h
, i
) {
1367 if (!output_show_unit_file(u
, strv_skip_first(args
)))
1374 assert(c
<= n_units
);
1377 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1379 r
= sd_bus_call_method(
1381 "org.freedesktop.systemd1",
1382 "/org/freedesktop/systemd1",
1383 "org.freedesktop.systemd1.Manager",
1389 log_error("Failed to list unit files: %s", bus_error_message(&error
, r
));
1393 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1395 return bus_log_parse_error(r
);
1397 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1399 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1402 units
[c
] = (struct UnitFileList
) {
1404 unit_file_state_from_string(state
)
1407 if (output_show_unit_file(&units
[c
], strv_skip_first(args
)))
1412 return bus_log_parse_error(r
);
1414 r
= sd_bus_message_exit_container(reply
);
1416 return bus_log_parse_error(r
);
1419 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1420 output_unit_file_list(units
, c
);
1423 for (unit
= units
; unit
< units
+ c
; unit
++)
1430 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1431 _cleanup_free_
char *n
= NULL
;
1432 size_t max_len
= MAX(columns(),20u);
1438 for (i
= level
- 1; i
>= 0; i
--) {
1440 if (len
> max_len
- 3 && !arg_full
) {
1441 printf("%s...\n",max_len
% 2 ? "" : " ");
1444 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1448 if (len
> max_len
- 3 && !arg_full
) {
1449 printf("%s...\n",max_len
% 2 ? "" : " ");
1453 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1457 printf("%s\n", name
);
1461 n
= ellipsize(name
, max_len
-len
, 100);
1469 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1471 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1472 [DEPENDENCY_FORWARD
] = "Requires\0"
1473 "RequiresOverridable\0"
1475 "RequisiteOverridable\0"
1479 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1480 "RequiredByOverridable\0"
1482 "RequisiteOfOverridable\0"
1486 [DEPENDENCY_AFTER
] = "After\0",
1487 [DEPENDENCY_BEFORE
] = "Before\0",
1490 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1491 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1492 _cleanup_strv_free_
char **ret
= NULL
;
1493 _cleanup_free_
char *path
= NULL
;
1499 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1501 path
= unit_dbus_path_from_name(name
);
1505 r
= sd_bus_call_method(
1507 "org.freedesktop.systemd1",
1509 "org.freedesktop.DBus.Properties",
1513 "s", "org.freedesktop.systemd1.Unit");
1515 log_error("Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1519 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1521 return bus_log_parse_error(r
);
1523 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1526 r
= sd_bus_message_read(reply
, "s", &prop
);
1528 return bus_log_parse_error(r
);
1530 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1531 r
= sd_bus_message_skip(reply
, "v");
1533 return bus_log_parse_error(r
);
1536 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1538 return bus_log_parse_error(r
);
1540 r
= bus_message_read_strv_extend(reply
, &ret
);
1542 return bus_log_parse_error(r
);
1544 r
= sd_bus_message_exit_container(reply
);
1546 return bus_log_parse_error(r
);
1549 r
= sd_bus_message_exit_container(reply
);
1551 return bus_log_parse_error(r
);
1555 return bus_log_parse_error(r
);
1557 r
= sd_bus_message_exit_container(reply
);
1559 return bus_log_parse_error(r
);
1567 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1568 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1570 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1572 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1575 return strcasecmp(*a
, *b
);
1578 static int list_dependencies_one(
1583 unsigned int branches
) {
1585 _cleanup_strv_free_
char **deps
= NULL
;
1593 r
= strv_extend(units
, name
);
1597 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1601 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1603 STRV_FOREACH(c
, deps
) {
1604 if (strv_contains(*units
, *c
)) {
1606 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1619 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1620 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1621 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1624 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1628 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1629 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1636 strv_remove(*units
, name
);
1641 static int list_dependencies(sd_bus
*bus
, char **args
) {
1642 _cleanup_strv_free_
char **units
= NULL
;
1643 _cleanup_free_
char *unit
= NULL
;
1650 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &unit
);
1652 return log_error_errno(r
, "Failed to mangle unit name: %m");
1656 u
= SPECIAL_DEFAULT_TARGET
;
1658 pager_open_if_enabled();
1662 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1665 struct machine_info
{
1669 char *control_group
;
1670 uint32_t n_failed_units
;
1675 static const struct bus_properties_map machine_info_property_map
[] = {
1676 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1677 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1678 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1679 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1680 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1684 static void machine_info_clear(struct machine_info
*info
) {
1688 free(info
->control_group
);
1693 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1699 for (i
= 0; i
< n
; i
++)
1700 machine_info_clear(&machine_infos
[i
]);
1702 free(machine_infos
);
1705 static int compare_machine_info(const void *a
, const void *b
) {
1706 const struct machine_info
*u
= a
, *v
= b
;
1708 if (u
->is_host
!= v
->is_host
)
1709 return u
->is_host
> v
->is_host
? -1 : 1;
1711 return strcasecmp(u
->name
, v
->name
);
1714 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1715 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1721 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1728 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1735 static bool output_show_machine(const char *name
, char **patterns
) {
1736 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1739 static int get_machine_list(
1741 struct machine_info
**_machine_infos
,
1744 struct machine_info
*machine_infos
= NULL
;
1745 _cleanup_strv_free_
char **m
= NULL
;
1746 _cleanup_free_
char *hn
= NULL
;
1751 hn
= gethostname_malloc();
1755 if (output_show_machine(hn
, patterns
)) {
1756 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1759 machine_infos
[c
].is_host
= true;
1760 machine_infos
[c
].name
= hn
;
1763 get_machine_properties(bus
, &machine_infos
[c
]);
1767 r
= sd_get_machine_names(&m
);
1769 return log_error_errno(r
, "Failed to get machine list: %m");
1771 STRV_FOREACH(i
, m
) {
1772 _cleanup_free_
char *class = NULL
;
1774 if (!output_show_machine(*i
, patterns
))
1777 sd_machine_get_class(*i
, &class);
1778 if (!streq_ptr(class, "container"))
1781 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1782 free_machines_list(machine_infos
, c
);
1786 machine_infos
[c
].is_host
= false;
1787 machine_infos
[c
].name
= strdup(*i
);
1788 if (!machine_infos
[c
].name
) {
1789 free_machines_list(machine_infos
, c
);
1793 get_machine_properties(NULL
, &machine_infos
[c
]);
1797 *_machine_infos
= machine_infos
;
1801 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1802 struct machine_info
*m
;
1805 namelen
= sizeof("NAME") - 1,
1806 statelen
= sizeof("STATE") - 1,
1807 failedlen
= sizeof("FAILED") - 1,
1808 jobslen
= sizeof("JOBS") - 1;
1810 assert(machine_infos
|| n
== 0);
1812 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1813 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1814 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1815 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1816 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1818 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1822 if (!arg_no_legend
) {
1826 printf("%-*s %-*s %-*s %-*s\n",
1829 failedlen
, "FAILED",
1833 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1834 const char *on_state
= "", *off_state
= "";
1835 const char *on_failed
= "", *off_failed
= "";
1836 bool circle
= false;
1838 if (streq_ptr(m
->state
, "degraded")) {
1839 on_state
= ansi_highlight_red();
1840 off_state
= ansi_normal();
1842 } else if (!streq_ptr(m
->state
, "running")) {
1843 on_state
= ansi_highlight_yellow();
1844 off_state
= ansi_normal();
1848 if (m
->n_failed_units
> 0) {
1849 on_failed
= ansi_highlight_red();
1850 off_failed
= ansi_normal();
1852 on_failed
= off_failed
= "";
1855 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1858 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1859 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1860 on_state
, statelen
, strna(m
->state
), off_state
,
1861 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1862 jobslen
, m
->n_jobs
);
1864 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1865 namelen
, strna(m
->name
),
1866 on_state
, statelen
, strna(m
->state
), off_state
,
1867 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1868 jobslen
, m
->n_jobs
);
1872 printf("\n%u machines listed.\n", n
);
1875 static int list_machines(sd_bus
*bus
, char **args
) {
1876 struct machine_info
*machine_infos
= NULL
;
1881 if (geteuid() != 0) {
1882 log_error("Must be root.");
1886 pager_open_if_enabled();
1888 r
= get_machine_list(bus
, &machine_infos
, strv_skip_first(args
));
1892 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1893 output_machines_list(machine_infos
, r
);
1894 free_machines_list(machine_infos
, r
);
1899 static int get_default(sd_bus
*bus
, char **args
) {
1900 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1901 _cleanup_free_
char *_path
= NULL
;
1905 if (!bus
|| avoid_bus()) {
1906 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1908 return log_error_errno(r
, "Failed to get default target: %m");
1912 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1914 r
= sd_bus_call_method(
1916 "org.freedesktop.systemd1",
1917 "/org/freedesktop/systemd1",
1918 "org.freedesktop.systemd1.Manager",
1924 log_error("Failed to get default target: %s", bus_error_message(&error
, -r
));
1928 r
= sd_bus_message_read(reply
, "s", &path
);
1930 return bus_log_parse_error(r
);
1934 printf("%s\n", path
);
1939 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1942 assert(changes
|| n_changes
== 0);
1944 for (i
= 0; i
< n_changes
; i
++) {
1945 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1946 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1948 log_info("Removed symlink %s.", changes
[i
].path
);
1952 static int set_default(sd_bus
*bus
, char **args
) {
1953 _cleanup_free_
char *unit
= NULL
;
1954 UnitFileChange
*changes
= NULL
;
1955 unsigned n_changes
= 0;
1958 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1960 return log_error_errno(r
, "Failed to mangle unit name: %m");
1962 if (!bus
|| avoid_bus()) {
1963 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1965 return log_error_errno(r
, "Failed to set default target: %m");
1968 dump_unit_file_changes(changes
, n_changes
);
1972 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1973 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1975 polkit_agent_open_if_enabled();
1977 r
= sd_bus_call_method(
1979 "org.freedesktop.systemd1",
1980 "/org/freedesktop/systemd1",
1981 "org.freedesktop.systemd1.Manager",
1987 log_error("Failed to set default target: %s", bus_error_message(&error
, -r
));
1991 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
1995 /* Try to reload if enabled */
1997 r
= daemon_reload(bus
, args
);
2002 unit_file_changes_free(changes
, n_changes
);
2009 const char *name
, *type
, *state
;
2012 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2013 unsigned id_len
, unit_len
, type_len
, state_len
;
2014 const struct job_info
*j
;
2015 const char *on
, *off
;
2016 bool shorten
= false;
2018 assert(n
== 0 || jobs
);
2021 if (!arg_no_legend
) {
2022 on
= ansi_highlight_green();
2023 off
= ansi_normal();
2025 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2030 pager_open_if_enabled();
2032 id_len
= strlen("JOB");
2033 unit_len
= strlen("UNIT");
2034 type_len
= strlen("TYPE");
2035 state_len
= strlen("STATE");
2037 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2038 uint32_t id
= j
->id
;
2039 assert(j
->name
&& j
->type
&& j
->state
);
2041 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2042 unit_len
= MAX(unit_len
, strlen(j
->name
));
2043 type_len
= MAX(type_len
, strlen(j
->type
));
2044 state_len
= MAX(state_len
, strlen(j
->state
));
2047 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2048 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2053 printf("%*s %-*s %-*s %-*s\n",
2057 state_len
, "STATE");
2059 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2060 _cleanup_free_
char *e
= NULL
;
2062 if (streq(j
->state
, "running")) {
2063 on
= ansi_highlight();
2064 off
= ansi_normal();
2068 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2069 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2071 on
, unit_len
, e
? e
: j
->name
, off
,
2073 on
, state_len
, j
->state
, off
);
2076 if (!arg_no_legend
) {
2077 on
= ansi_highlight();
2078 off
= ansi_normal();
2080 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2084 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2085 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2088 static int list_jobs(sd_bus
*bus
, char **args
) {
2089 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2090 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2091 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2092 _cleanup_free_
struct job_info
*jobs
= NULL
;
2097 bool skipped
= false;
2099 r
= sd_bus_call_method(
2101 "org.freedesktop.systemd1",
2102 "/org/freedesktop/systemd1",
2103 "org.freedesktop.systemd1.Manager",
2109 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
2113 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2115 return bus_log_parse_error(r
);
2117 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2118 struct job_info job
= { id
, name
, type
, state
};
2120 if (!output_show_job(&job
, strv_skip_first(args
))) {
2125 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2131 return bus_log_parse_error(r
);
2133 r
= sd_bus_message_exit_container(reply
);
2135 return bus_log_parse_error(r
);
2137 output_jobs_list(jobs
, c
, skipped
);
2141 static int cancel_job(sd_bus
*bus
, char **args
) {
2147 if (strv_length(args
) <= 1)
2148 return daemon_reload(bus
, args
);
2150 polkit_agent_open_if_enabled();
2152 STRV_FOREACH(name
, args
+1) {
2153 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2157 q
= safe_atou32(*name
, &id
);
2159 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2161 q
= sd_bus_call_method(
2163 "org.freedesktop.systemd1",
2164 "/org/freedesktop/systemd1",
2165 "org.freedesktop.systemd1.Manager",
2171 log_error("Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2180 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2181 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2185 /* We ignore all errors here, since this is used to show a
2188 /* We don't use unit_dbus_path_from_name() directly since we
2189 * don't want to load the unit if it isn't loaded. */
2191 r
= sd_bus_call_method(
2193 "org.freedesktop.systemd1",
2194 "/org/freedesktop/systemd1",
2195 "org.freedesktop.systemd1.Manager",
2203 r
= sd_bus_message_read(reply
, "o", &path
);
2207 r
= sd_bus_get_property_trivial(
2209 "org.freedesktop.systemd1",
2211 "org.freedesktop.systemd1.Unit",
2221 static void warn_unit_file_changed(const char *name
) {
2222 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2223 ansi_highlight_red(),
2226 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2229 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2236 STRV_FOREACH(p
, lp
->unit_path
) {
2237 _cleanup_free_
char *path
;
2239 path
= path_join(arg_root
, *p
, unit_name
);
2243 if (access(path
, F_OK
) == 0) {
2253 static int unit_find_paths(
2255 const char *unit_name
,
2256 bool avoid_bus_cache
,
2258 char **fragment_path
,
2259 char ***dropin_paths
) {
2261 _cleanup_free_
char *path
= NULL
;
2262 _cleanup_strv_free_
char **dropins
= NULL
;
2266 * Finds where the unit is defined on disk. Returns 0 if the unit
2267 * is not found. Returns 1 if it is found, and sets
2268 * - the path to the unit in *path, if it exists on disk,
2269 * - and a strv of existing drop-ins in *dropins,
2270 * if the arg is not NULL and any dropins were found.
2274 assert(fragment_path
);
2277 if (!avoid_bus_cache
&& !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2278 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2279 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2280 _cleanup_free_
char *unit
= NULL
;
2281 char *unit_load_error_name
, *unit_load_error_message
;
2283 unit
= unit_dbus_path_from_name(unit_name
);
2287 if (need_daemon_reload(bus
, unit_name
) > 0)
2288 warn_unit_file_changed(unit_name
);
2290 r
= sd_bus_get_property(
2292 "org.freedesktop.systemd1",
2294 "org.freedesktop.systemd1.Unit",
2300 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2302 r
= sd_bus_message_read(
2305 &unit_load_error_name
,
2306 &unit_load_error_message
);
2308 return bus_log_parse_error(r
);
2310 if (!isempty(unit_load_error_name
)) {
2311 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2315 r
= sd_bus_get_property_string(
2317 "org.freedesktop.systemd1",
2319 "org.freedesktop.systemd1.Unit",
2324 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2327 r
= sd_bus_get_property_strv(
2329 "org.freedesktop.systemd1",
2331 "org.freedesktop.systemd1.Unit",
2336 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2339 _cleanup_set_free_ Set
*names
;
2341 names
= set_new(NULL
);
2345 r
= set_put(names
, unit_name
);
2347 return log_error_errno(r
, "Failed to add unit name: %m");
2349 r
= unit_file_find_path(lp
, unit_name
, &path
);
2354 _cleanup_free_
char *template = NULL
;
2356 r
= unit_name_template(unit_name
, &template);
2357 if (r
< 0 && r
!= -EINVAL
)
2358 return log_error_errno(r
, "Failed to determine template name: %m");
2360 r
= unit_file_find_path(lp
, template, &path
);
2367 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2375 if (!isempty(path
)) {
2376 *fragment_path
= path
;
2381 if (dropin_paths
&& !strv_isempty(dropins
)) {
2382 *dropin_paths
= dropins
;
2388 log_error("No files found for %s.", unit_name
);
2393 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2394 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2395 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2401 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2403 return log_error_errno(r
, "Failed to mangle unit name: %m");
2405 /* We don't use unit_dbus_path_from_name() directly since we
2406 * don't want to load the unit if it isn't loaded. */
2408 r
= sd_bus_call_method(
2410 "org.freedesktop.systemd1",
2411 "/org/freedesktop/systemd1",
2412 "org.freedesktop.systemd1.Manager",
2423 r
= sd_bus_message_read(reply
, "o", &path
);
2425 return bus_log_parse_error(r
);
2427 r
= sd_bus_get_property_string(
2429 "org.freedesktop.systemd1",
2431 "org.freedesktop.systemd1.Unit",
2444 return nulstr_contains(good_states
, state
);
2447 static int check_triggering_units(
2451 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2452 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2453 _cleanup_strv_free_
char **triggered_by
= NULL
;
2454 bool print_warning_label
= true;
2458 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2460 return log_error_errno(r
, "Failed to mangle unit name: %m");
2462 path
= unit_dbus_path_from_name(n
);
2466 r
= sd_bus_get_property_string(
2468 "org.freedesktop.systemd1",
2470 "org.freedesktop.systemd1.Unit",
2475 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2479 if (streq(state
, "masked"))
2482 r
= sd_bus_get_property_strv(
2484 "org.freedesktop.systemd1",
2486 "org.freedesktop.systemd1.Unit",
2491 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2495 STRV_FOREACH(i
, triggered_by
) {
2496 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2498 return log_error_errno(r
, "Failed to check unit: %m");
2503 if (print_warning_label
) {
2504 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2505 print_warning_label
= false;
2508 log_warning(" %s", *i
);
2514 static const struct {
2517 } unit_actions
[] = {
2518 { "start", "StartUnit" },
2519 { "stop", "StopUnit" },
2520 { "condstop", "StopUnit" },
2521 { "reload", "ReloadUnit" },
2522 { "restart", "RestartUnit" },
2523 { "try-restart", "TryRestartUnit" },
2524 { "condrestart", "TryRestartUnit" },
2525 { "reload-or-restart", "ReloadOrRestartUnit" },
2526 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2527 { "condreload", "ReloadOrTryRestartUnit" },
2528 { "force-reload", "ReloadOrTryRestartUnit" }
2531 static const char *verb_to_method(const char *verb
) {
2534 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2535 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2536 return unit_actions
[i
].method
;
2541 static const char *method_to_verb(const char *method
) {
2544 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2545 if (streq_ptr(unit_actions
[i
].method
, method
))
2546 return unit_actions
[i
].verb
;
2551 static int start_unit_one(
2556 sd_bus_error
*error
,
2557 BusWaitForJobs
*w
) {
2559 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2568 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2570 r
= sd_bus_call_method(
2572 "org.freedesktop.systemd1",
2573 "/org/freedesktop/systemd1",
2574 "org.freedesktop.systemd1.Manager",
2582 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2583 /* There's always a fallback possible for
2584 * legacy actions. */
2585 return -EADDRNOTAVAIL
;
2587 verb
= method_to_verb(method
);
2589 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2593 r
= sd_bus_message_read(reply
, "o", &path
);
2595 return bus_log_parse_error(r
);
2597 if (need_daemon_reload(bus
, name
) > 0)
2598 warn_unit_file_changed(name
);
2601 log_debug("Adding %s to the set", path
);
2602 r
= bus_wait_for_jobs_add(w
, path
);
2610 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2612 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2616 STRV_FOREACH(name
, names
) {
2620 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2622 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2624 return log_error_errno(r
, "Failed to mangle name: %m");
2626 if (string_is_glob(t
))
2627 r
= strv_consume(&globs
, t
);
2629 r
= strv_consume(&mangled
, t
);
2634 /* Query the manager only if any of the names are a glob, since
2635 * this is fairly expensive */
2636 if (!strv_isempty(globs
)) {
2637 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2638 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2641 return log_error_errno(EOPNOTSUPP
, "Unit name globbing without bus is not implemented.");
2643 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2647 for (i
= 0; i
< r
; i
++)
2648 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2653 mangled
= NULL
; /* do not free */
2658 static const struct {
2662 } action_table
[_ACTION_MAX
] = {
2663 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2664 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2665 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2666 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2667 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2668 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2669 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2670 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2671 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2672 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2673 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2674 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2675 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2676 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2677 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2680 static enum action
verb_to_action(const char *verb
) {
2683 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2684 if (streq_ptr(action_table
[i
].verb
, verb
))
2687 return _ACTION_INVALID
;
2690 static int start_unit(sd_bus
*bus
, char **args
) {
2691 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2692 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2693 _cleanup_strv_free_
char **names
= NULL
;
2699 ask_password_agent_open_if_enabled();
2700 polkit_agent_open_if_enabled();
2702 if (arg_action
== ACTION_SYSTEMCTL
) {
2704 method
= verb_to_method(args
[0]);
2705 action
= verb_to_action(args
[0]);
2707 if (streq(args
[0], "isolate")) {
2711 mode
= action_table
[action
].mode
?: arg_job_mode
;
2713 one_name
= action_table
[action
].target
;
2715 assert(arg_action
< ELEMENTSOF(action_table
));
2716 assert(action_table
[arg_action
].target
);
2718 method
= "StartUnit";
2720 mode
= action_table
[arg_action
].mode
;
2721 one_name
= action_table
[arg_action
].target
;
2725 names
= strv_new(one_name
, NULL
);
2727 r
= expand_names(bus
, args
+ 1, suffix
, &names
);
2729 log_error_errno(r
, "Failed to expand names: %m");
2732 if (!arg_no_block
) {
2733 r
= bus_wait_for_jobs_new(bus
, &w
);
2735 return log_error_errno(r
, "Could not watch jobs: %m");
2738 STRV_FOREACH(name
, names
) {
2739 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2742 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2743 if (r
>= 0 && q
< 0)
2744 r
= translate_bus_error_to_exit_status(q
, &error
);
2747 if (!arg_no_block
) {
2750 q
= bus_wait_for_jobs(w
, arg_quiet
);
2754 /* When stopping units, warn if they can still be triggered by
2755 * another active unit (socket, path, timer) */
2756 if (!arg_quiet
&& streq(method
, "StopUnit"))
2757 STRV_FOREACH(name
, names
)
2758 check_triggering_units(bus
, *name
);
2764 /* Ask systemd-logind, which might grant access to unprivileged users
2765 * through PolicyKit */
2766 static int reboot_with_logind(sd_bus
*bus
, enum action a
) {
2768 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2769 const char *method
, *description
;
2775 polkit_agent_open_if_enabled();
2781 description
= "reboot system";
2784 case ACTION_POWEROFF
:
2785 method
= "PowerOff";
2786 description
= "power off system";
2789 case ACTION_SUSPEND
:
2791 description
= "suspend system";
2794 case ACTION_HIBERNATE
:
2795 method
= "Hibernate";
2796 description
= "hibernate system";
2799 case ACTION_HYBRID_SLEEP
:
2800 method
= "HybridSleep";
2801 description
= "put system into hybrid sleep";
2808 if (!strv_isempty(arg_wall
)) {
2809 _cleanup_free_
char *m
;
2811 m
= strv_join(arg_wall
, " ");
2815 r
= sd_bus_call_method(
2817 "org.freedesktop.login1",
2818 "/org/freedesktop/login1",
2819 "org.freedesktop.login1.Manager",
2828 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
2829 bus_error_message(&error
, r
));
2830 sd_bus_error_free(&error
);
2835 r
= sd_bus_call_method(
2837 "org.freedesktop.login1",
2838 "/org/freedesktop/login1",
2839 "org.freedesktop.login1.Manager",
2843 "b", arg_ask_password
);
2845 log_error("Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2853 static int check_inhibitors(sd_bus
*bus
, enum action a
) {
2855 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2856 _cleanup_strv_free_
char **sessions
= NULL
;
2857 const char *what
, *who
, *why
, *mode
;
2866 if (arg_ignore_inhibitors
|| arg_force
> 0)
2878 r
= sd_bus_call_method(
2880 "org.freedesktop.login1",
2881 "/org/freedesktop/login1",
2882 "org.freedesktop.login1.Manager",
2888 /* If logind is not around, then there are no inhibitors... */
2891 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2893 return bus_log_parse_error(r
);
2895 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2896 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2897 _cleanup_strv_free_
char **sv
= NULL
;
2899 if (!streq(mode
, "block"))
2902 sv
= strv_split(what
, ":");
2906 if ((pid_t
) pid
< 0)
2907 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2909 if (!strv_contains(sv
,
2914 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2917 get_process_comm(pid
, &comm
);
2918 user
= uid_to_name(uid
);
2920 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2921 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2926 return bus_log_parse_error(r
);
2928 r
= sd_bus_message_exit_container(reply
);
2930 return bus_log_parse_error(r
);
2932 /* Check for current sessions */
2933 sd_get_sessions(&sessions
);
2934 STRV_FOREACH(s
, sessions
) {
2935 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2937 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2940 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2943 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2946 sd_session_get_tty(*s
, &tty
);
2947 sd_session_get_seat(*s
, &seat
);
2948 sd_session_get_service(*s
, &service
);
2949 user
= uid_to_name(uid
);
2951 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2958 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2959 action_table
[a
].verb
);
2967 static int prepare_firmware_setup(sd_bus
*bus
) {
2969 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2973 if (!arg_firmware_setup
)
2976 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
2978 r
= efi_set_reboot_to_firmware(true);
2980 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
2986 r
= sd_bus_call_method(
2988 "org.freedesktop.login1",
2989 "/org/freedesktop/login1",
2990 "org.freedesktop.login1.Manager",
2991 "SetRebootToFirmwareSetup",
2996 log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3002 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3007 static int start_special(sd_bus
*bus
, char **args
) {
3008 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3014 a
= verb_to_action(args
[0]);
3016 r
= check_inhibitors(bus
, a
);
3020 if (arg_force
>= 2 && geteuid() != 0) {
3021 log_error("Must be root.");
3025 r
= prepare_firmware_setup(bus
);
3029 if (a
== ACTION_REBOOT
&& args
[1]) {
3030 r
= update_reboot_param_file(args
[1]);
3033 } else if (a
== ACTION_EXIT
&& strv_length(args
) > 1) {
3034 /* If the exit code is not given on the command line, don't
3035 * reset it to zero: just keep it as it might have been set
3039 r
= safe_atou8(args
[1], &code
);
3041 log_error("Invalid exit code.");
3045 r
= sd_bus_call_method(
3047 "org.freedesktop.systemd1",
3048 "/org/freedesktop/systemd1",
3049 "org.freedesktop.systemd1.Manager",
3055 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
3060 if (arg_force
>= 2 &&
3067 if (arg_force
>= 1 &&
3074 return daemon_reload(bus
, args
);
3076 /* first try logind, to allow authentication with polkit */
3077 if (geteuid() != 0 &&
3083 ACTION_HYBRID_SLEEP
)) {
3084 r
= reboot_with_logind(bus
, a
);
3087 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3088 /* requested operation is not supported or already in progress */
3090 /* on all other errors, try low-level operation */
3093 r
= start_unit(bus
, args
);
3094 if (r
== EXIT_SUCCESS
)
3100 static int check_unit_generic(sd_bus
*bus
, int code
, const char *good_states
, char **args
) {
3101 _cleanup_strv_free_
char **names
= NULL
;
3108 r
= expand_names(bus
, args
, NULL
, &names
);
3110 return log_error_errno(r
, "Failed to expand names: %m");
3112 STRV_FOREACH(name
, names
) {
3115 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3125 static int check_unit_active(sd_bus
*bus
, char **args
) {
3126 /* According to LSB: 3, "program is not running" */
3127 return check_unit_generic(bus
, 3, "active\0reloading\0", args
+ 1);
3130 static int check_unit_failed(sd_bus
*bus
, char **args
) {
3131 return check_unit_generic(bus
, 1, "failed\0", args
+ 1);
3134 static int kill_unit(sd_bus
*bus
, char **args
) {
3135 _cleanup_strv_free_
char **names
= NULL
;
3136 char *kill_who
= NULL
, **name
;
3142 polkit_agent_open_if_enabled();
3145 arg_kill_who
= "all";
3147 /* --fail was specified */
3148 if (streq(arg_job_mode
, "fail"))
3149 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3151 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
3153 log_error_errno(r
, "Failed to expand names: %m");
3155 STRV_FOREACH(name
, names
) {
3156 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3158 q
= sd_bus_call_method(
3160 "org.freedesktop.systemd1",
3161 "/org/freedesktop/systemd1",
3162 "org.freedesktop.systemd1.Manager",
3166 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3168 log_error("Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3177 typedef struct ExecStatusInfo
{
3185 usec_t start_timestamp
;
3186 usec_t exit_timestamp
;
3191 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3194 static void exec_status_info_free(ExecStatusInfo
*i
) {
3203 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3204 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3207 int32_t code
, status
;
3213 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3215 return bus_log_parse_error(r
);
3219 r
= sd_bus_message_read(m
, "s", &path
);
3221 return bus_log_parse_error(r
);
3223 i
->path
= strdup(path
);
3227 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3229 return bus_log_parse_error(r
);
3231 r
= sd_bus_message_read(m
,
3234 &start_timestamp
, &start_timestamp_monotonic
,
3235 &exit_timestamp
, &exit_timestamp_monotonic
,
3239 return bus_log_parse_error(r
);
3242 i
->start_timestamp
= (usec_t
) start_timestamp
;
3243 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3244 i
->pid
= (pid_t
) pid
;
3248 r
= sd_bus_message_exit_container(m
);
3250 return bus_log_parse_error(r
);
3255 typedef struct UnitStatusInfo
{
3257 const char *load_state
;
3258 const char *active_state
;
3259 const char *sub_state
;
3260 const char *unit_file_state
;
3261 const char *unit_file_preset
;
3263 const char *description
;
3264 const char *following
;
3266 char **documentation
;
3268 const char *fragment_path
;
3269 const char *source_path
;
3270 const char *control_group
;
3272 char **dropin_paths
;
3274 const char *load_error
;
3277 usec_t inactive_exit_timestamp
;
3278 usec_t inactive_exit_timestamp_monotonic
;
3279 usec_t active_enter_timestamp
;
3280 usec_t active_exit_timestamp
;
3281 usec_t inactive_enter_timestamp
;
3283 bool need_daemon_reload
;
3288 const char *status_text
;
3289 const char *pid_file
;
3293 usec_t start_timestamp
;
3294 usec_t exit_timestamp
;
3296 int exit_code
, exit_status
;
3298 usec_t condition_timestamp
;
3299 bool condition_result
;
3300 bool failed_condition_trigger
;
3301 bool failed_condition_negate
;
3302 const char *failed_condition
;
3303 const char *failed_condition_parameter
;
3305 usec_t assert_timestamp
;
3307 bool failed_assert_trigger
;
3308 bool failed_assert_negate
;
3309 const char *failed_assert
;
3310 const char *failed_assert_parameter
;
3313 unsigned n_accepted
;
3314 unsigned n_connections
;
3317 /* Pairs of type, path */
3321 const char *sysfs_path
;
3323 /* Mount, Automount */
3330 uint64_t memory_current
;
3331 uint64_t memory_limit
;
3332 uint64_t cpu_usage_nsec
;
3333 uint64_t tasks_current
;
3336 LIST_HEAD(ExecStatusInfo
, exec
);
3339 static void print_status_info(
3344 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3346 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3347 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3353 /* This shows pretty information about a unit. See
3354 * print_property() for a low-level property printer */
3356 if (streq_ptr(i
->active_state
, "failed")) {
3357 active_on
= ansi_highlight_red();
3358 active_off
= ansi_normal();
3359 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3360 active_on
= ansi_highlight_green();
3361 active_off
= ansi_normal();
3363 active_on
= active_off
= "";
3365 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3367 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3368 printf(" - %s", i
->description
);
3373 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3375 if (streq_ptr(i
->load_state
, "error")) {
3376 on
= ansi_highlight_red();
3377 off
= ansi_normal();
3381 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3384 printf(" Loaded: %s%s%s (Reason: %s)\n",
3385 on
, strna(i
->load_state
), off
, i
->load_error
);
3386 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3387 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3388 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3389 else if (path
&& !isempty(i
->unit_file_state
))
3390 printf(" Loaded: %s%s%s (%s; %s)\n",
3391 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3393 printf(" Loaded: %s%s%s (%s)\n",
3394 on
, strna(i
->load_state
), off
, path
);
3396 printf(" Loaded: %s%s%s\n",
3397 on
, strna(i
->load_state
), off
);
3399 if (!strv_isempty(i
->dropin_paths
)) {
3400 _cleanup_free_
char *dir
= NULL
;
3404 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3405 if (! dir
|| last
) {
3406 printf(dir
? " " : " Drop-In: ");
3410 if (path_get_parent(*dropin
, &dir
) < 0) {
3415 printf("%s\n %s", dir
,
3416 draw_special_char(DRAW_TREE_RIGHT
));
3419 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3421 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3425 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3427 printf(" Active: %s%s (%s)%s",
3428 active_on
, strna(i
->active_state
), ss
, active_off
);
3430 printf(" Active: %s%s%s",
3431 active_on
, strna(i
->active_state
), active_off
);
3433 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3434 printf(" (Result: %s)", i
->result
);
3436 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3437 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3438 (streq_ptr(i
->active_state
, "inactive") ||
3439 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3440 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3441 i
->active_exit_timestamp
;
3443 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3444 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3447 printf(" since %s; %s\n", s2
, s1
);
3449 printf(" since %s\n", s2
);
3453 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3454 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3455 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3457 printf("Condition: start %scondition failed%s at %s%s%s\n",
3458 ansi_highlight_yellow(), ansi_normal(),
3459 s2
, s1
? "; " : "", s1
? s1
: "");
3460 if (i
->failed_condition_trigger
)
3461 printf(" none of the trigger conditions were met\n");
3462 else if (i
->failed_condition
)
3463 printf(" %s=%s%s was not met\n",
3464 i
->failed_condition
,
3465 i
->failed_condition_negate
? "!" : "",
3466 i
->failed_condition_parameter
);
3469 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3470 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3471 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3473 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3474 ansi_highlight_red(), ansi_normal(),
3475 s2
, s1
? "; " : "", s1
? s1
: "");
3476 if (i
->failed_assert_trigger
)
3477 printf(" none of the trigger assertions were met\n");
3478 else if (i
->failed_assert
)
3479 printf(" %s=%s%s was not met\n",
3481 i
->failed_assert_negate
? "!" : "",
3482 i
->failed_assert_parameter
);
3486 printf(" Device: %s\n", i
->sysfs_path
);
3488 printf(" Where: %s\n", i
->where
);
3490 printf(" What: %s\n", i
->what
);
3492 STRV_FOREACH(t
, i
->documentation
)
3493 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3495 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3496 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3499 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3501 LIST_FOREACH(exec
, p
, i
->exec
) {
3502 _cleanup_free_
char *argv
= NULL
;
3505 /* Only show exited processes here */
3509 argv
= strv_join(p
->argv
, " ");
3510 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3512 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3514 on
= ansi_highlight_red();
3515 off
= ansi_normal();
3519 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3521 if (p
->code
== CLD_EXITED
) {
3524 printf("status=%i", p
->status
);
3526 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3531 printf("signal=%s", signal_to_string(p
->status
));
3533 printf(")%s\n", off
);
3535 if (i
->main_pid
== p
->pid
&&
3536 i
->start_timestamp
== p
->start_timestamp
&&
3537 i
->exit_timestamp
== p
->start_timestamp
)
3538 /* Let's not show this twice */
3541 if (p
->pid
== i
->control_pid
)
3545 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3546 if (i
->main_pid
> 0) {
3547 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3550 _cleanup_free_
char *comm
= NULL
;
3551 get_process_comm(i
->main_pid
, &comm
);
3553 printf(" (%s)", comm
);
3554 } else if (i
->exit_code
> 0) {
3555 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3557 if (i
->exit_code
== CLD_EXITED
) {
3560 printf("status=%i", i
->exit_status
);
3562 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3567 printf("signal=%s", signal_to_string(i
->exit_status
));
3571 if (i
->control_pid
> 0)
3575 if (i
->control_pid
> 0) {
3576 _cleanup_free_
char *c
= NULL
;
3578 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3580 get_process_comm(i
->control_pid
, &c
);
3589 printf(" Status: \"%s\"\n", i
->status_text
);
3590 if (i
->status_errno
> 0)
3591 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3593 if (i
->tasks_current
!= (uint64_t) -1) {
3594 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3596 if (i
->tasks_max
!= (uint64_t) -1)
3597 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3602 if (i
->memory_current
!= (uint64_t) -1) {
3603 char buf
[FORMAT_BYTES_MAX
];
3605 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3607 if (i
->memory_limit
!= (uint64_t) -1)
3608 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3613 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3614 char buf
[FORMAT_TIMESPAN_MAX
];
3615 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3618 if (i
->control_group
&&
3619 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3620 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3623 printf(" CGroup: %s\n", i
->control_group
);
3625 if (IN_SET(arg_transport
,
3626 BUS_TRANSPORT_LOCAL
,
3627 BUS_TRANSPORT_MACHINE
)) {
3630 static const char prefix
[] = " ";
3633 if (c
> sizeof(prefix
) - 1)
3634 c
-= sizeof(prefix
) - 1;
3638 if (i
->main_pid
> 0)
3639 extra
[k
++] = i
->main_pid
;
3641 if (i
->control_pid
> 0)
3642 extra
[k
++] = i
->control_pid
;
3644 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3648 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3649 show_journal_by_unit(
3654 i
->inactive_exit_timestamp_monotonic
,
3657 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3658 SD_JOURNAL_LOCAL_ONLY
,
3659 arg_scope
== UNIT_FILE_SYSTEM
,
3662 if (i
->need_daemon_reload
)
3663 warn_unit_file_changed(i
->id
);
3666 static void show_unit_help(UnitStatusInfo
*i
) {
3671 if (!i
->documentation
) {
3672 log_info("Documentation for %s not known.", i
->id
);
3676 STRV_FOREACH(p
, i
->documentation
)
3677 if (startswith(*p
, "man:"))
3678 show_man_page(*p
+ 4, false);
3680 log_info("Can't show: %s", *p
);
3683 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3690 switch (contents
[0]) {
3692 case SD_BUS_TYPE_STRING
: {
3695 r
= sd_bus_message_read(m
, "s", &s
);
3697 return bus_log_parse_error(r
);
3700 if (streq(name
, "Id"))
3702 else if (streq(name
, "LoadState"))
3704 else if (streq(name
, "ActiveState"))
3705 i
->active_state
= s
;
3706 else if (streq(name
, "SubState"))
3708 else if (streq(name
, "Description"))
3710 else if (streq(name
, "FragmentPath"))
3711 i
->fragment_path
= s
;
3712 else if (streq(name
, "SourcePath"))
3715 else if (streq(name
, "DefaultControlGroup")) {
3717 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3719 i
->control_group
= e
;
3722 else if (streq(name
, "ControlGroup"))
3723 i
->control_group
= s
;
3724 else if (streq(name
, "StatusText"))
3726 else if (streq(name
, "PIDFile"))
3728 else if (streq(name
, "SysFSPath"))
3730 else if (streq(name
, "Where"))
3732 else if (streq(name
, "What"))
3734 else if (streq(name
, "Following"))
3736 else if (streq(name
, "UnitFileState"))
3737 i
->unit_file_state
= s
;
3738 else if (streq(name
, "UnitFilePreset"))
3739 i
->unit_file_preset
= s
;
3740 else if (streq(name
, "Result"))
3747 case SD_BUS_TYPE_BOOLEAN
: {
3750 r
= sd_bus_message_read(m
, "b", &b
);
3752 return bus_log_parse_error(r
);
3754 if (streq(name
, "Accept"))
3756 else if (streq(name
, "NeedDaemonReload"))
3757 i
->need_daemon_reload
= b
;
3758 else if (streq(name
, "ConditionResult"))
3759 i
->condition_result
= b
;
3760 else if (streq(name
, "AssertResult"))
3761 i
->assert_result
= b
;
3766 case SD_BUS_TYPE_UINT32
: {
3769 r
= sd_bus_message_read(m
, "u", &u
);
3771 return bus_log_parse_error(r
);
3773 if (streq(name
, "MainPID")) {
3775 i
->main_pid
= (pid_t
) u
;
3778 } else if (streq(name
, "ControlPID"))
3779 i
->control_pid
= (pid_t
) u
;
3780 else if (streq(name
, "ExecMainPID")) {
3782 i
->main_pid
= (pid_t
) u
;
3783 } else if (streq(name
, "NAccepted"))
3785 else if (streq(name
, "NConnections"))
3786 i
->n_connections
= u
;
3791 case SD_BUS_TYPE_INT32
: {
3794 r
= sd_bus_message_read(m
, "i", &j
);
3796 return bus_log_parse_error(r
);
3798 if (streq(name
, "ExecMainCode"))
3799 i
->exit_code
= (int) j
;
3800 else if (streq(name
, "ExecMainStatus"))
3801 i
->exit_status
= (int) j
;
3802 else if (streq(name
, "StatusErrno"))
3803 i
->status_errno
= (int) j
;
3808 case SD_BUS_TYPE_UINT64
: {
3811 r
= sd_bus_message_read(m
, "t", &u
);
3813 return bus_log_parse_error(r
);
3815 if (streq(name
, "ExecMainStartTimestamp"))
3816 i
->start_timestamp
= (usec_t
) u
;
3817 else if (streq(name
, "ExecMainExitTimestamp"))
3818 i
->exit_timestamp
= (usec_t
) u
;
3819 else if (streq(name
, "ActiveEnterTimestamp"))
3820 i
->active_enter_timestamp
= (usec_t
) u
;
3821 else if (streq(name
, "InactiveEnterTimestamp"))
3822 i
->inactive_enter_timestamp
= (usec_t
) u
;
3823 else if (streq(name
, "InactiveExitTimestamp"))
3824 i
->inactive_exit_timestamp
= (usec_t
) u
;
3825 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3826 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3827 else if (streq(name
, "ActiveExitTimestamp"))
3828 i
->active_exit_timestamp
= (usec_t
) u
;
3829 else if (streq(name
, "ConditionTimestamp"))
3830 i
->condition_timestamp
= (usec_t
) u
;
3831 else if (streq(name
, "AssertTimestamp"))
3832 i
->assert_timestamp
= (usec_t
) u
;
3833 else if (streq(name
, "MemoryCurrent"))
3834 i
->memory_current
= u
;
3835 else if (streq(name
, "MemoryLimit"))
3836 i
->memory_limit
= u
;
3837 else if (streq(name
, "TasksCurrent"))
3838 i
->tasks_current
= u
;
3839 else if (streq(name
, "TasksMax"))
3841 else if (streq(name
, "CPUUsageNSec"))
3842 i
->cpu_usage_nsec
= u
;
3847 case SD_BUS_TYPE_ARRAY
:
3849 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3850 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3852 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3854 return bus_log_parse_error(r
);
3856 info
= new0(ExecStatusInfo
, 1);
3860 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3862 info
->name
= strdup(name
);
3866 LIST_PREPEND(exec
, i
->exec
, info
);
3868 info
= new0(ExecStatusInfo
, 1);
3874 return bus_log_parse_error(r
);
3876 r
= sd_bus_message_exit_container(m
);
3878 return bus_log_parse_error(r
);
3882 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3883 const char *type
, *path
;
3885 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3887 return bus_log_parse_error(r
);
3889 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3891 r
= strv_extend(&i
->listen
, type
);
3895 r
= strv_extend(&i
->listen
, path
);
3900 return bus_log_parse_error(r
);
3902 r
= sd_bus_message_exit_container(m
);
3904 return bus_log_parse_error(r
);
3908 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3910 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3912 return bus_log_parse_error(r
);
3914 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3916 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3918 return bus_log_parse_error(r
);
3920 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3921 const char *cond
, *param
;
3922 int trigger
, negate
;
3925 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3927 return bus_log_parse_error(r
);
3929 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3930 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3931 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3932 i
->failed_condition
= cond
;
3933 i
->failed_condition_trigger
= trigger
;
3934 i
->failed_condition_negate
= negate
;
3935 i
->failed_condition_parameter
= param
;
3939 return bus_log_parse_error(r
);
3941 r
= sd_bus_message_exit_container(m
);
3943 return bus_log_parse_error(r
);
3945 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
3946 const char *cond
, *param
;
3947 int trigger
, negate
;
3950 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3952 return bus_log_parse_error(r
);
3954 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3955 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3956 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
3957 i
->failed_assert
= cond
;
3958 i
->failed_assert_trigger
= trigger
;
3959 i
->failed_assert_negate
= negate
;
3960 i
->failed_assert_parameter
= param
;
3964 return bus_log_parse_error(r
);
3966 r
= sd_bus_message_exit_container(m
);
3968 return bus_log_parse_error(r
);
3975 case SD_BUS_TYPE_STRUCT_BEGIN
:
3977 if (streq(name
, "LoadError")) {
3978 const char *n
, *message
;
3980 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3982 return bus_log_parse_error(r
);
3984 if (!isempty(message
))
3985 i
->load_error
= message
;
3998 r
= sd_bus_message_skip(m
, contents
);
4000 return bus_log_parse_error(r
);
4005 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4011 /* This is a low-level property printer, see
4012 * print_status_info() for the nicer output */
4014 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4015 /* skip what we didn't read */
4016 r
= sd_bus_message_skip(m
, contents
);
4020 switch (contents
[0]) {
4022 case SD_BUS_TYPE_STRUCT_BEGIN
:
4024 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4027 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4029 return bus_log_parse_error(r
);
4032 printf("%s=%"PRIu32
"\n", name
, u
);
4034 printf("%s=\n", name
);
4038 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4041 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4043 return bus_log_parse_error(r
);
4045 if (arg_all
|| !isempty(s
))
4046 printf("%s=%s\n", name
, s
);
4050 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4051 const char *a
= NULL
, *b
= NULL
;
4053 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4055 return bus_log_parse_error(r
);
4057 if (arg_all
|| !isempty(a
) || !isempty(b
))
4058 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4061 } else if (streq_ptr(name
, "SystemCallFilter")) {
4062 _cleanup_strv_free_
char **l
= NULL
;
4065 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4067 return bus_log_parse_error(r
);
4069 r
= sd_bus_message_read(m
, "b", &whitelist
);
4071 return bus_log_parse_error(r
);
4073 r
= sd_bus_message_read_strv(m
, &l
);
4075 return bus_log_parse_error(r
);
4077 r
= sd_bus_message_exit_container(m
);
4079 return bus_log_parse_error(r
);
4081 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4085 fputs(name
, stdout
);
4091 STRV_FOREACH(i
, l
) {
4099 fputc('\n', stdout
);
4107 case SD_BUS_TYPE_ARRAY
:
4109 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4113 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4115 return bus_log_parse_error(r
);
4117 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4118 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4121 return bus_log_parse_error(r
);
4123 r
= sd_bus_message_exit_container(m
);
4125 return bus_log_parse_error(r
);
4129 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4130 const char *type
, *path
;
4132 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4134 return bus_log_parse_error(r
);
4136 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4137 printf("%s=%s\n", type
, path
);
4139 return bus_log_parse_error(r
);
4141 r
= sd_bus_message_exit_container(m
);
4143 return bus_log_parse_error(r
);
4147 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4148 const char *type
, *path
;
4150 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4152 return bus_log_parse_error(r
);
4154 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4155 printf("Listen%s=%s\n", type
, path
);
4157 return bus_log_parse_error(r
);
4159 r
= sd_bus_message_exit_container(m
);
4161 return bus_log_parse_error(r
);
4165 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4167 uint64_t value
, next_elapse
;
4169 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4171 return bus_log_parse_error(r
);
4173 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4174 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4176 printf("%s={ value=%s ; next_elapse=%s }\n",
4178 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4179 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4182 return bus_log_parse_error(r
);
4184 r
= sd_bus_message_exit_container(m
);
4186 return bus_log_parse_error(r
);
4190 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4191 ExecStatusInfo info
= {};
4193 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4195 return bus_log_parse_error(r
);
4197 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4198 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4199 _cleanup_free_
char *tt
;
4201 tt
= strv_join(info
.argv
, " ");
4203 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",
4207 yes_no(info
.ignore
),
4208 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4209 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4211 sigchld_code_to_string(info
.code
),
4213 info
.code
== CLD_EXITED
? "" : "/",
4214 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4217 strv_free(info
.argv
);
4221 r
= sd_bus_message_exit_container(m
);
4223 return bus_log_parse_error(r
);
4227 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4228 const char *path
, *rwm
;
4230 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4232 return bus_log_parse_error(r
);
4234 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4235 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4237 return bus_log_parse_error(r
);
4239 r
= sd_bus_message_exit_container(m
);
4241 return bus_log_parse_error(r
);
4245 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4249 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4251 return bus_log_parse_error(r
);
4253 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4254 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4256 return bus_log_parse_error(r
);
4258 r
= sd_bus_message_exit_container(m
);
4260 return bus_log_parse_error(r
);
4264 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4268 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4270 return bus_log_parse_error(r
);
4272 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4273 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4275 return bus_log_parse_error(r
);
4277 r
= sd_bus_message_exit_container(m
);
4279 return bus_log_parse_error(r
);
4287 r
= bus_print_property(name
, m
, arg_all
);
4289 return bus_log_parse_error(r
);
4292 r
= sd_bus_message_skip(m
, contents
);
4294 return bus_log_parse_error(r
);
4297 printf("%s=[unprintable]\n", name
);
4303 static int show_one(
4307 bool show_properties
,
4311 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4312 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4313 UnitStatusInfo info
= {
4314 .memory_current
= (uint64_t) -1,
4315 .memory_limit
= (uint64_t) -1,
4316 .cpu_usage_nsec
= (uint64_t) -1,
4317 .tasks_current
= (uint64_t) -1,
4318 .tasks_max
= (uint64_t) -1,
4326 log_debug("Showing one %s", path
);
4328 r
= sd_bus_call_method(
4330 "org.freedesktop.systemd1",
4332 "org.freedesktop.DBus.Properties",
4338 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4340 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4342 return bus_log_parse_error(r
);
4349 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4350 const char *name
, *contents
;
4352 r
= sd_bus_message_read(reply
, "s", &name
);
4354 return bus_log_parse_error(r
);
4356 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4358 return bus_log_parse_error(r
);
4360 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4362 return bus_log_parse_error(r
);
4364 if (show_properties
)
4365 r
= print_property(name
, reply
, contents
);
4367 r
= status_property(name
, reply
, &info
, contents
);
4371 r
= sd_bus_message_exit_container(reply
);
4373 return bus_log_parse_error(r
);
4375 r
= sd_bus_message_exit_container(reply
);
4377 return bus_log_parse_error(r
);
4380 return bus_log_parse_error(r
);
4382 r
= sd_bus_message_exit_container(reply
);
4384 return bus_log_parse_error(r
);
4388 if (!show_properties
) {
4389 if (streq(verb
, "help"))
4390 show_unit_help(&info
);
4392 print_status_info(&info
, ellipsized
);
4395 strv_free(info
.documentation
);
4396 strv_free(info
.dropin_paths
);
4397 strv_free(info
.listen
);
4399 if (!streq_ptr(info
.active_state
, "active") &&
4400 !streq_ptr(info
.active_state
, "reloading") &&
4401 streq(verb
, "status")) {
4402 /* According to LSB: "program not running" */
4403 /* 0: program is running or service is OK
4404 * 1: program is dead and /run PID file exists
4405 * 2: program is dead and /run/lock lock file exists
4406 * 3: program is not running
4407 * 4: program or service status is unknown
4409 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4415 while ((p
= info
.exec
)) {
4416 LIST_REMOVE(exec
, info
.exec
, p
);
4417 exec_status_info_free(p
);
4423 static int get_unit_dbus_path_by_pid(
4428 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4429 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4433 r
= sd_bus_call_method(
4435 "org.freedesktop.systemd1",
4436 "/org/freedesktop/systemd1",
4437 "org.freedesktop.systemd1.Manager",
4443 log_error("Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4447 r
= sd_bus_message_read(reply
, "o", &u
);
4449 return bus_log_parse_error(r
);
4459 static int show_all(
4462 bool show_properties
,
4466 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4467 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4472 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4476 pager_open_if_enabled();
4480 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4482 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4483 _cleanup_free_
char *p
= NULL
;
4485 p
= unit_dbus_path_from_name(u
->id
);
4489 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4492 else if (r
> 0 && ret
== 0)
4499 static int show_system_status(sd_bus
*bus
) {
4500 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4501 _cleanup_free_
char *hn
= NULL
;
4502 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4503 const char *on
, *off
;
4506 hn
= gethostname_malloc();
4510 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4512 return log_error_errno(r
, "Failed to read server status: %m");
4514 if (streq_ptr(mi
.state
, "degraded")) {
4515 on
= ansi_highlight_red();
4516 off
= ansi_normal();
4517 } else if (!streq_ptr(mi
.state
, "running")) {
4518 on
= ansi_highlight_yellow();
4519 off
= ansi_normal();
4523 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4525 printf(" State: %s%s%s\n",
4526 on
, strna(mi
.state
), off
);
4528 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4529 printf(" Failed: %u units\n", mi
.n_failed_units
);
4531 printf(" Since: %s; %s\n",
4532 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4533 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4535 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4536 if (IN_SET(arg_transport
,
4537 BUS_TRANSPORT_LOCAL
,
4538 BUS_TRANSPORT_MACHINE
)) {
4539 static const char prefix
[] = " ";
4543 if (c
> sizeof(prefix
) - 1)
4544 c
-= sizeof(prefix
) - 1;
4548 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4554 static int show(sd_bus
*bus
, char **args
) {
4555 bool show_properties
, show_status
, new_line
= false;
4556 bool ellipsized
= false;
4562 show_properties
= streq(args
[0], "show");
4563 show_status
= streq(args
[0], "status");
4565 if (show_properties
)
4566 pager_open_if_enabled();
4569 /* Increase max number of open files to 16K if we can, we
4570 * might needs this when browsing journal files, which might
4571 * be split up into many files. */
4572 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4574 /* If no argument is specified inspect the manager itself */
4576 if (show_properties
&& strv_length(args
) <= 1)
4577 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4579 if (show_status
&& strv_length(args
) <= 1) {
4581 pager_open_if_enabled();
4582 show_system_status(bus
);
4586 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
4588 _cleanup_free_
char **patterns
= NULL
;
4591 STRV_FOREACH(name
, args
+ 1) {
4592 _cleanup_free_
char *unit
= NULL
;
4595 if (safe_atou32(*name
, &id
) < 0) {
4596 if (strv_push(&patterns
, *name
) < 0)
4600 } else if (show_properties
) {
4601 /* Interpret as job id */
4602 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4606 /* Interpret as PID */
4607 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4614 r
= show_one(args
[0], bus
, unit
, show_properties
,
4615 &new_line
, &ellipsized
);
4618 else if (r
> 0 && ret
== 0)
4622 if (!strv_isempty(patterns
)) {
4623 _cleanup_strv_free_
char **names
= NULL
;
4625 r
= expand_names(bus
, patterns
, NULL
, &names
);
4627 log_error_errno(r
, "Failed to expand names: %m");
4629 STRV_FOREACH(name
, names
) {
4630 _cleanup_free_
char *unit
;
4632 unit
= unit_dbus_path_from_name(*name
);
4636 r
= show_one(args
[0], bus
, unit
, show_properties
,
4637 &new_line
, &ellipsized
);
4640 else if (r
> 0 && ret
== 0)
4646 if (ellipsized
&& !arg_quiet
)
4647 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4652 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4656 assert(user_runtime
);
4659 if (arg_scope
== UNIT_FILE_USER
) {
4660 r
= user_config_home(user_home
);
4662 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4664 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4666 r
= user_runtime_dir(user_runtime
);
4668 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4670 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4673 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4675 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4680 static int cat_file(const char *filename
, bool newline
) {
4681 _cleanup_close_
int fd
;
4683 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4687 printf("%s%s# %s%s\n",
4688 newline
? "\n" : "",
4689 ansi_highlight_blue(),
4694 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4697 static int cat(sd_bus
*bus
, char **args
) {
4698 _cleanup_free_
char *user_home
= NULL
;
4699 _cleanup_free_
char *user_runtime
= NULL
;
4700 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4701 _cleanup_strv_free_
char **names
= NULL
;
4703 bool first
= true, avoid_bus_cache
;
4708 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4709 log_error("Cannot remotely cat units");
4713 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4717 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4719 return log_error_errno(r
, "Failed to expand names: %m");
4721 avoid_bus_cache
= !bus
|| avoid_bus();
4723 pager_open_if_enabled();
4725 STRV_FOREACH(name
, names
) {
4726 _cleanup_free_
char *fragment_path
= NULL
;
4727 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4730 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &fragment_path
, &dropin_paths
);
4741 if (fragment_path
) {
4742 r
= cat_file(fragment_path
, false);
4744 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4747 STRV_FOREACH(path
, dropin_paths
) {
4748 r
= cat_file(*path
, path
== dropin_paths
);
4750 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4757 static int set_property(sd_bus
*bus
, char **args
) {
4758 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4759 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4760 _cleanup_free_
char *n
= NULL
;
4764 polkit_agent_open_if_enabled();
4766 r
= sd_bus_message_new_method_call(
4769 "org.freedesktop.systemd1",
4770 "/org/freedesktop/systemd1",
4771 "org.freedesktop.systemd1.Manager",
4772 "SetUnitProperties");
4774 return bus_log_create_error(r
);
4776 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &n
);
4778 return log_error_errno(r
, "Failed to mangle unit name: %m");
4780 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4782 return bus_log_create_error(r
);
4784 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4786 return bus_log_create_error(r
);
4788 STRV_FOREACH(i
, args
+ 2) {
4789 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4791 return bus_log_create_error(r
);
4793 r
= bus_append_unit_property_assignment(m
, *i
);
4797 r
= sd_bus_message_close_container(m
);
4799 return bus_log_create_error(r
);
4802 r
= sd_bus_message_close_container(m
);
4804 return bus_log_create_error(r
);
4806 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4808 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4815 static int snapshot(sd_bus
*bus
, char **args
) {
4816 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4817 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4818 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4822 polkit_agent_open_if_enabled();
4824 if (strv_length(args
) > 1) {
4825 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4827 return log_error_errno(r
, "Failed to generate unit name: %m");
4834 r
= sd_bus_call_method(
4836 "org.freedesktop.systemd1",
4837 "/org/freedesktop/systemd1",
4838 "org.freedesktop.systemd1.Manager",
4844 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
4848 r
= sd_bus_message_read(reply
, "o", &path
);
4850 return bus_log_parse_error(r
);
4852 r
= sd_bus_get_property_string(
4854 "org.freedesktop.systemd1",
4856 "org.freedesktop.systemd1.Unit",
4861 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4871 static int delete_snapshot(sd_bus
*bus
, char **args
) {
4872 _cleanup_strv_free_
char **names
= NULL
;
4878 polkit_agent_open_if_enabled();
4880 r
= expand_names(bus
, args
+ 1, ".snapshot", &names
);
4882 log_error_errno(r
, "Failed to expand names: %m");
4884 STRV_FOREACH(name
, names
) {
4885 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4888 q
= sd_bus_call_method(
4890 "org.freedesktop.systemd1",
4891 "/org/freedesktop/systemd1",
4892 "org.freedesktop.systemd1.Manager",
4898 log_error("Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4907 static int daemon_reload(sd_bus
*bus
, char **args
) {
4908 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4912 polkit_agent_open_if_enabled();
4914 if (arg_action
== ACTION_RELOAD
)
4916 else if (arg_action
== ACTION_REEXEC
)
4917 method
= "Reexecute";
4919 assert(arg_action
== ACTION_SYSTEMCTL
);
4922 streq(args
[0], "clear-jobs") ||
4923 streq(args
[0], "cancel") ? "ClearJobs" :
4924 streq(args
[0], "daemon-reexec") ? "Reexecute" :
4925 streq(args
[0], "reset-failed") ? "ResetFailed" :
4926 streq(args
[0], "halt") ? "Halt" :
4927 streq(args
[0], "poweroff") ? "PowerOff" :
4928 streq(args
[0], "reboot") ? "Reboot" :
4929 streq(args
[0], "kexec") ? "KExec" :
4930 streq(args
[0], "exit") ? "Exit" :
4931 /* "daemon-reload" */ "Reload";
4934 r
= sd_bus_call_method(
4936 "org.freedesktop.systemd1",
4937 "/org/freedesktop/systemd1",
4938 "org.freedesktop.systemd1.Manager",
4943 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4944 /* There's always a fallback possible for
4945 * legacy actions. */
4947 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4948 /* On reexecution, we expect a disconnect, not a
4952 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4954 return r
< 0 ? r
: 0;
4957 static int reset_failed(sd_bus
*bus
, char **args
) {
4958 _cleanup_strv_free_
char **names
= NULL
;
4962 if (strv_length(args
) <= 1)
4963 return daemon_reload(bus
, args
);
4965 polkit_agent_open_if_enabled();
4967 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4969 log_error_errno(r
, "Failed to expand names: %m");
4971 STRV_FOREACH(name
, names
) {
4972 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4974 q
= sd_bus_call_method(
4976 "org.freedesktop.systemd1",
4977 "/org/freedesktop/systemd1",
4978 "org.freedesktop.systemd1.Manager",
4984 log_error("Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4993 static int show_environment(sd_bus
*bus
, char **args
) {
4994 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4995 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4999 pager_open_if_enabled();
5001 r
= sd_bus_get_property(
5003 "org.freedesktop.systemd1",
5004 "/org/freedesktop/systemd1",
5005 "org.freedesktop.systemd1.Manager",
5011 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
5015 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5017 return bus_log_parse_error(r
);
5019 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5022 return bus_log_parse_error(r
);
5024 r
= sd_bus_message_exit_container(reply
);
5026 return bus_log_parse_error(r
);
5031 static int switch_root(sd_bus
*bus
, char **args
) {
5032 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5033 _cleanup_free_
char *cmdline_init
= NULL
;
5034 const char *root
, *init
;
5038 l
= strv_length(args
);
5039 if (l
< 2 || l
> 3) {
5040 log_error("Wrong number of arguments.");
5049 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5050 "init", &cmdline_init
,
5053 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5055 init
= cmdline_init
;
5062 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5064 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5065 root_init_path
= strjoina(root
, "/", init
);
5067 /* If the passed init is actually the same as the
5068 * systemd binary, then let's suppress it. */
5069 if (files_same(root_init_path
, root_systemd_path
) > 0)
5073 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5075 r
= sd_bus_call_method(
5077 "org.freedesktop.systemd1",
5078 "/org/freedesktop/systemd1",
5079 "org.freedesktop.systemd1.Manager",
5085 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
5092 static int set_environment(sd_bus
*bus
, char **args
) {
5093 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5094 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5101 polkit_agent_open_if_enabled();
5103 method
= streq(args
[0], "set-environment")
5105 : "UnsetEnvironment";
5107 r
= sd_bus_message_new_method_call(
5110 "org.freedesktop.systemd1",
5111 "/org/freedesktop/systemd1",
5112 "org.freedesktop.systemd1.Manager",
5115 return bus_log_create_error(r
);
5117 r
= sd_bus_message_append_strv(m
, args
+ 1);
5119 return bus_log_create_error(r
);
5121 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5123 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
5130 static int import_environment(sd_bus
*bus
, char **args
) {
5131 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5132 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5138 polkit_agent_open_if_enabled();
5140 r
= sd_bus_message_new_method_call(
5143 "org.freedesktop.systemd1",
5144 "/org/freedesktop/systemd1",
5145 "org.freedesktop.systemd1.Manager",
5148 return bus_log_create_error(r
);
5150 if (strv_isempty(args
+ 1))
5151 r
= sd_bus_message_append_strv(m
, environ
);
5155 r
= sd_bus_message_open_container(m
, 'a', "s");
5157 return bus_log_create_error(r
);
5159 STRV_FOREACH(a
, args
+ 1) {
5161 if (!env_name_is_valid(*a
)) {
5162 log_error("Not a valid environment variable name: %s", *a
);
5166 STRV_FOREACH(b
, environ
) {
5169 eq
= startswith(*b
, *a
);
5170 if (eq
&& *eq
== '=') {
5172 r
= sd_bus_message_append(m
, "s", *b
);
5174 return bus_log_create_error(r
);
5181 r
= sd_bus_message_close_container(m
);
5184 return bus_log_create_error(r
);
5186 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5188 log_error("Failed to import environment: %s", bus_error_message(&error
, r
));
5195 static int enable_sysv_units(const char *verb
, char **args
) {
5198 #if defined(HAVE_SYSV_COMPAT)
5200 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5202 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5205 if (!STR_IN_SET(verb
,
5211 /* Processes all SysV units, and reshuffles the array so that
5212 * afterwards only the native units remain */
5214 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5221 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5222 bool found_native
= false, found_sysv
;
5224 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5232 if (!endswith(name
, ".service"))
5235 if (path_is_absolute(name
))
5238 STRV_FOREACH(k
, paths
.unit_path
) {
5239 _cleanup_free_
char *path
= NULL
;
5241 path
= path_join(arg_root
, *k
, name
);
5245 found_native
= access(path
, F_OK
) >= 0;
5250 /* If we have both a native unit and a SysV script,
5251 * enable/disable them both (below); for is-enabled, prefer the
5253 if (found_native
&& streq(verb
, "is-enabled"))
5256 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5260 p
[strlen(p
) - strlen(".service")] = 0;
5261 found_sysv
= access(p
, F_OK
) >= 0;
5266 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5268 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5270 if (!isempty(arg_root
))
5271 argv
[c
++] = q
= strappend("--root=", arg_root
);
5274 argv
[c
++] = basename(p
);
5277 l
= strv_join((char**)argv
, " ");
5281 log_info("Executing %s", l
);
5285 return log_error_errno(errno
, "Failed to fork: %m");
5286 else if (pid
== 0) {
5289 (void) reset_all_signal_handlers();
5290 (void) reset_signal_mask();
5292 execv(argv
[0], (char**) argv
);
5293 log_error("Failed to execute %s: %m", argv
[0]);
5294 _exit(EXIT_FAILURE
);
5297 j
= wait_for_terminate(pid
, &status
);
5299 log_error_errno(r
, "Failed to wait for child: %m");
5303 if (status
.si_code
== CLD_EXITED
) {
5304 if (streq(verb
, "is-enabled")) {
5305 if (status
.si_status
== 0) {
5314 } else if (status
.si_status
!= 0)
5322 /* Remove this entry, so that we don't try enabling it as native unit */
5325 assert(args
[f
] == name
);
5326 strv_remove(args
, name
);
5333 static int mangle_names(char **original_names
, char ***mangled_names
) {
5334 char **i
, **l
, **name
;
5337 l
= i
= new(char*, strv_length(original_names
) + 1);
5341 STRV_FOREACH(name
, original_names
) {
5343 /* When enabling units qualified path names are OK,
5344 * too, hence allow them explicitly. */
5346 if (is_path(*name
)) {
5353 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5356 return log_error_errno(r
, "Failed to mangle unit name: %m");
5369 static int enable_unit(sd_bus
*bus
, char **args
) {
5370 _cleanup_strv_free_
char **names
= NULL
;
5371 const char *verb
= args
[0];
5372 UnitFileChange
*changes
= NULL
;
5373 unsigned n_changes
= 0;
5374 int carries_install_info
= -1;
5380 r
= mangle_names(args
+1, &names
);
5384 r
= enable_sysv_units(verb
, names
);
5388 /* If the operation was fully executed by the SysV compat,
5389 * let's finish early */
5390 if (strv_isempty(names
))
5393 if (!bus
|| avoid_bus()) {
5394 if (streq(verb
, "enable")) {
5395 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5396 carries_install_info
= r
;
5397 } else if (streq(verb
, "disable"))
5398 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5399 else if (streq(verb
, "reenable")) {
5400 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5401 carries_install_info
= r
;
5402 } else if (streq(verb
, "link"))
5403 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5404 else if (streq(verb
, "preset")) {
5405 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5406 carries_install_info
= r
;
5407 } else if (streq(verb
, "mask"))
5408 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5409 else if (streq(verb
, "unmask"))
5410 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5412 assert_not_reached("Unknown verb");
5415 log_error_errno(r
, "Operation failed: %m");
5420 dump_unit_file_changes(changes
, n_changes
);
5424 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5425 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5426 int expect_carries_install_info
= false;
5427 bool send_force
= true, send_preset_mode
= false;
5430 polkit_agent_open_if_enabled();
5432 if (streq(verb
, "enable")) {
5433 method
= "EnableUnitFiles";
5434 expect_carries_install_info
= true;
5435 } else if (streq(verb
, "disable")) {
5436 method
= "DisableUnitFiles";
5438 } else if (streq(verb
, "reenable")) {
5439 method
= "ReenableUnitFiles";
5440 expect_carries_install_info
= true;
5441 } else if (streq(verb
, "link"))
5442 method
= "LinkUnitFiles";
5443 else if (streq(verb
, "preset")) {
5445 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5446 method
= "PresetUnitFilesWithMode";
5447 send_preset_mode
= true;
5449 method
= "PresetUnitFiles";
5451 expect_carries_install_info
= true;
5452 } else if (streq(verb
, "mask"))
5453 method
= "MaskUnitFiles";
5454 else if (streq(verb
, "unmask")) {
5455 method
= "UnmaskUnitFiles";
5458 assert_not_reached("Unknown verb");
5460 r
= sd_bus_message_new_method_call(
5463 "org.freedesktop.systemd1",
5464 "/org/freedesktop/systemd1",
5465 "org.freedesktop.systemd1.Manager",
5468 return bus_log_create_error(r
);
5470 r
= sd_bus_message_append_strv(m
, names
);
5472 return bus_log_create_error(r
);
5474 if (send_preset_mode
) {
5475 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5477 return bus_log_create_error(r
);
5480 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5482 return bus_log_create_error(r
);
5485 r
= sd_bus_message_append(m
, "b", arg_force
);
5487 return bus_log_create_error(r
);
5490 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5492 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5496 if (expect_carries_install_info
) {
5497 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5499 return bus_log_parse_error(r
);
5502 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5506 /* Try to reload if enabled */
5508 r
= daemon_reload(bus
, args
);
5513 if (carries_install_info
== 0)
5514 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5515 "using systemctl.\n"
5516 "Possible reasons for having this kind of units are:\n"
5517 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5518 " .wants/ or .requires/ directory.\n"
5519 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5520 " a requirement dependency on it.\n"
5521 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5522 " D-Bus, udev, scripted systemctl call, ...).\n");
5524 if (arg_now
&& n_changes
> 0 && STR_IN_SET(args
[0], "enable", "disable", "mask")) {
5525 char *new_args
[n_changes
+ 2];
5528 new_args
[0] = streq(args
[0], "enable") ? (char *)"start" : (char *)"stop";
5529 for (i
= 0; i
< n_changes
; i
++)
5530 new_args
[i
+ 1] = basename(changes
[i
].path
);
5531 new_args
[i
+ 1] = NULL
;
5533 r
= start_unit(bus
, new_args
);
5537 unit_file_changes_free(changes
, n_changes
);
5542 static int add_dependency(sd_bus
*bus
, char **args
) {
5543 _cleanup_strv_free_
char **names
= NULL
;
5544 _cleanup_free_
char *target
= NULL
;
5545 const char *verb
= args
[0];
5552 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5554 return log_error_errno(r
, "Failed to mangle unit name: %m");
5556 r
= mangle_names(args
+2, &names
);
5560 if (streq(verb
, "add-wants"))
5562 else if (streq(verb
, "add-requires"))
5563 dep
= UNIT_REQUIRES
;
5565 assert_not_reached("Unknown verb");
5567 if (!bus
|| avoid_bus()) {
5568 UnitFileChange
*changes
= NULL
;
5569 unsigned n_changes
= 0;
5571 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5574 return log_error_errno(r
, "Can't add dependency: %m");
5577 dump_unit_file_changes(changes
, n_changes
);
5579 unit_file_changes_free(changes
, n_changes
);
5582 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5583 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5585 polkit_agent_open_if_enabled();
5587 r
= sd_bus_message_new_method_call(
5590 "org.freedesktop.systemd1",
5591 "/org/freedesktop/systemd1",
5592 "org.freedesktop.systemd1.Manager",
5593 "AddDependencyUnitFiles");
5595 return bus_log_create_error(r
);
5597 r
= sd_bus_message_append_strv(m
, names
);
5599 return bus_log_create_error(r
);
5601 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5603 return bus_log_create_error(r
);
5605 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5607 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5611 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5616 r
= daemon_reload(bus
, args
);
5624 static int preset_all(sd_bus
*bus
, char **args
) {
5625 UnitFileChange
*changes
= NULL
;
5626 unsigned n_changes
= 0;
5629 if (!bus
|| avoid_bus()) {
5631 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5633 log_error_errno(r
, "Operation failed: %m");
5638 dump_unit_file_changes(changes
, n_changes
);
5643 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5644 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5646 polkit_agent_open_if_enabled();
5648 r
= sd_bus_call_method(
5650 "org.freedesktop.systemd1",
5651 "/org/freedesktop/systemd1",
5652 "org.freedesktop.systemd1.Manager",
5653 "PresetAllUnitFiles",
5657 unit_file_preset_mode_to_string(arg_preset_mode
),
5661 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5665 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5670 r
= daemon_reload(bus
, args
);
5676 unit_file_changes_free(changes
, n_changes
);
5681 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
5683 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5684 _cleanup_strv_free_
char **names
= NULL
;
5689 r
= mangle_names(args
+1, &names
);
5693 r
= enable_sysv_units(args
[0], names
);
5699 if (!bus
|| avoid_bus()) {
5701 STRV_FOREACH(name
, names
) {
5702 UnitFileState state
;
5704 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5706 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5710 UNIT_FILE_ENABLED_RUNTIME
,
5712 UNIT_FILE_INDIRECT
))
5716 puts(unit_file_state_to_string(state
));
5720 STRV_FOREACH(name
, names
) {
5721 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5724 r
= sd_bus_call_method(
5726 "org.freedesktop.systemd1",
5727 "/org/freedesktop/systemd1",
5728 "org.freedesktop.systemd1.Manager",
5734 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5738 r
= sd_bus_message_read(reply
, "s", &s
);
5740 return bus_log_parse_error(r
);
5742 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5753 static int is_system_running(sd_bus
*bus
, char **args
) {
5754 _cleanup_free_
char *state
= NULL
;
5757 r
= sd_bus_get_property_string(
5759 "org.freedesktop.systemd1",
5760 "/org/freedesktop/systemd1",
5761 "org.freedesktop.systemd1.Manager",
5774 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5777 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5782 assert(original_path
);
5785 r
= tempfn_random(new_path
, NULL
, &t
);
5787 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5789 r
= mkdir_parents(new_path
, 0755);
5791 log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5796 r
= copy_file(original_path
, t
, 0, 0644, 0);
5800 log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5805 log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5815 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5816 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5818 switch (arg_scope
) {
5819 case UNIT_FILE_SYSTEM
:
5820 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5822 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5824 case UNIT_FILE_GLOBAL
:
5825 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5827 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5829 case UNIT_FILE_USER
:
5831 assert(user_runtime
);
5833 path
= path_join(arg_root
, user_home
, name
);
5835 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5838 run
= path_join(arg_root
, user_runtime
, name
);
5842 assert_not_reached("Invalid scope");
5844 if (!path
|| (arg_runtime
&& !run
))
5848 if (access(path
, F_OK
) >= 0)
5849 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5851 if (path2
&& access(path2
, F_OK
) >= 0)
5852 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5864 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
) {
5865 char *tmp_new_path
, *ending
;
5870 assert(ret_new_path
);
5871 assert(ret_tmp_path
);
5873 ending
= strjoina(unit_name
, ".d/override.conf");
5874 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5878 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5884 *ret_new_path
= tmp_new_path
;
5885 *ret_tmp_path
= tmp_tmp_path
;
5890 static int unit_file_create_copy(
5891 const char *unit_name
,
5892 const char *fragment_path
,
5893 const char *user_home
,
5894 const char *user_runtime
,
5895 char **ret_new_path
,
5896 char **ret_tmp_path
) {
5902 assert(fragment_path
);
5904 assert(ret_new_path
);
5905 assert(ret_tmp_path
);
5907 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5911 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5914 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5919 if (response
!= 'y') {
5920 log_warning("%s ignored", unit_name
);
5926 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5928 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5933 *ret_new_path
= tmp_new_path
;
5934 *ret_tmp_path
= tmp_tmp_path
;
5939 static int run_editor(char **paths
) {
5947 log_error_errno(errno
, "Failed to fork: %m");
5953 char *editor
, **editor_args
= NULL
;
5954 char **tmp_path
, **original_path
, *p
;
5955 unsigned n_editor_args
= 0, i
= 1;
5958 (void) reset_all_signal_handlers();
5959 (void) reset_signal_mask();
5961 argc
= strv_length(paths
)/2 + 1;
5963 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5964 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5965 * we try to execute well known editors
5967 editor
= getenv("SYSTEMD_EDITOR");
5969 editor
= getenv("EDITOR");
5971 editor
= getenv("VISUAL");
5973 if (!isempty(editor
)) {
5974 editor_args
= strv_split(editor
, WHITESPACE
);
5977 _exit(EXIT_FAILURE
);
5979 n_editor_args
= strv_length(editor_args
);
5980 argc
+= n_editor_args
- 1;
5982 args
= newa(const char*, argc
+ 1);
5984 if (n_editor_args
> 0) {
5985 args
[0] = editor_args
[0];
5986 for (; i
< n_editor_args
; i
++)
5987 args
[i
] = editor_args
[i
];
5990 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
5991 args
[i
] = *tmp_path
;
5996 if (n_editor_args
> 0)
5997 execvp(args
[0], (char* const*) args
);
5999 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6001 execvp(p
, (char* const*) args
);
6002 /* We do not fail if the editor doesn't exist
6003 * because we want to try each one of them before
6006 if (errno
!= ENOENT
) {
6007 log_error("Failed to execute %s: %m", editor
);
6008 _exit(EXIT_FAILURE
);
6012 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6013 _exit(EXIT_FAILURE
);
6016 r
= wait_for_terminate_and_warn("editor", pid
, true);
6018 return log_error_errno(r
, "Failed to wait for child: %m");
6023 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6024 _cleanup_free_
char *user_home
= NULL
;
6025 _cleanup_free_
char *user_runtime
= NULL
;
6026 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6027 bool avoid_bus_cache
;
6034 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6038 avoid_bus_cache
= !bus
|| avoid_bus();
6040 STRV_FOREACH(name
, names
) {
6041 _cleanup_free_
char *path
= NULL
;
6042 char *new_path
, *tmp_path
;
6044 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &path
, NULL
);
6050 // FIXME: support units with path==NULL (no FragmentPath)
6051 log_error("No fragment exists for %s.", *name
);
6056 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6058 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6062 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6070 static int edit(sd_bus
*bus
, char **args
) {
6071 _cleanup_strv_free_
char **names
= NULL
;
6072 _cleanup_strv_free_
char **paths
= NULL
;
6073 char **original
, **tmp
;
6079 log_error("Cannot edit units if not on a tty");
6083 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6084 log_error("Cannot remotely edit units");
6088 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
6090 return log_error_errno(r
, "Failed to expand names: %m");
6092 r
= find_paths_to_edit(bus
, names
, &paths
);
6096 if (strv_isempty(paths
))
6099 r
= run_editor(paths
);
6103 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6104 /* If the temporary file is empty we ignore it.
6105 * It's useful if the user wants to cancel its modification
6107 if (null_or_empty_path(*tmp
)) {
6108 log_warning("Editing \"%s\" canceled: temporary file is empty", *original
);
6111 r
= rename(*tmp
, *original
);
6113 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6118 if (!arg_no_reload
&& bus
&& !avoid_bus())
6119 r
= daemon_reload(bus
, args
);
6122 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6123 unlink_noerrno(*tmp
);
6128 static void systemctl_help(void) {
6130 pager_open_if_enabled();
6132 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6133 "Query or send control commands to the systemd manager.\n\n"
6134 " -h --help Show this help\n"
6135 " --version Show package version\n"
6136 " --system Connect to system manager\n"
6137 " --user Connect to user service manager\n"
6138 " -H --host=[USER@]HOST\n"
6139 " Operate on remote host\n"
6140 " -M --machine=CONTAINER\n"
6141 " Operate on local container\n"
6142 " -t --type=TYPE List units of a particular type\n"
6143 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6144 " -p --property=NAME Show only properties by this name\n"
6145 " -a --all Show all loaded units/properties, including dead/empty\n"
6146 " ones. To list all units installed on the system, use\n"
6147 " the 'list-unit-files' command instead.\n"
6148 " -l --full Don't ellipsize unit names on output\n"
6149 " -r --recursive Show unit list of host and local containers\n"
6150 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6151 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6152 " queueing a new job\n"
6153 " --show-types When showing sockets, explicitly show their type\n"
6154 " -i --ignore-inhibitors\n"
6155 " When shutting down or sleeping, ignore inhibitors\n"
6156 " --kill-who=WHO Who to send signal to\n"
6157 " -s --signal=SIGNAL Which signal to send\n"
6158 " --now Start or stop unit in addition to enabling or disabling it\n"
6159 " -q --quiet Suppress output\n"
6160 " --no-block Do not wait until operation finished\n"
6161 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6162 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6163 " --no-legend Do not print a legend (column headers and hints)\n"
6164 " --no-pager Do not pipe output into a pager\n"
6165 " --no-ask-password\n"
6166 " Do not ask for system passwords\n"
6167 " --global Enable/disable unit files globally\n"
6168 " --runtime Enable unit files only temporarily until next reboot\n"
6169 " -f --force When enabling unit files, override existing symlinks\n"
6170 " When shutting down, execute action immediately\n"
6171 " --preset-mode= Apply only enable, only disable, or all presets\n"
6172 " --root=PATH Enable unit files in the specified root directory\n"
6173 " -n --lines=INTEGER Number of journal entries to show\n"
6174 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6175 " short-precise, short-monotonic, verbose,\n"
6176 " export, json, json-pretty, json-sse, cat)\n"
6177 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6178 " --plain Print unit dependencies as a list instead of a tree\n\n"
6180 " list-units [PATTERN...] List loaded units\n"
6181 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6182 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6183 " start NAME... Start (activate) one or more units\n"
6184 " stop NAME... Stop (deactivate) one or more units\n"
6185 " reload NAME... Reload one or more units\n"
6186 " restart NAME... Start or restart one or more units\n"
6187 " try-restart NAME... Restart one or more units if active\n"
6188 " reload-or-restart NAME... Reload one or more units if possible,\n"
6189 " otherwise start or restart\n"
6190 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6191 " otherwise restart if active\n"
6192 " isolate NAME Start one unit and stop all others\n"
6193 " kill NAME... Send signal to processes of a unit\n"
6194 " is-active PATTERN... Check whether units are active\n"
6195 " is-failed PATTERN... Check whether units are failed\n"
6196 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6197 " show [PATTERN...|JOB...] Show properties of one or more\n"
6198 " units/jobs or the manager\n"
6199 " cat PATTERN... Show files and drop-ins of one or more units\n"
6200 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6201 " help PATTERN...|PID... Show manual for one or more units\n"
6202 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6204 " list-dependencies [NAME] Recursively show units which are required\n"
6205 " or wanted by this unit or by which this\n"
6206 " unit is required or wanted\n\n"
6207 "Unit File Commands:\n"
6208 " list-unit-files [PATTERN...] List installed unit files\n"
6209 " enable NAME... Enable one or more unit files\n"
6210 " disable NAME... Disable one or more unit files\n"
6211 " reenable NAME... Reenable one or more unit files\n"
6212 " preset NAME... Enable/disable one or more unit files\n"
6213 " based on preset configuration\n"
6214 " preset-all Enable/disable all unit files based on\n"
6215 " preset configuration\n"
6216 " is-enabled NAME... Check whether unit files are enabled\n"
6217 " mask NAME... Mask one or more units\n"
6218 " unmask NAME... Unmask one or more units\n"
6219 " link PATH... Link one or more units files into\n"
6220 " the search path\n"
6221 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6222 " on specified one or more units\n"
6223 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6224 " on specified one or more units\n"
6225 " edit NAME... Edit one or more unit files\n"
6226 " get-default Get the name of the default target\n"
6227 " set-default NAME Set the default target\n\n"
6228 "Machine Commands:\n"
6229 " list-machines [PATTERN...] List local containers and host\n\n"
6231 " list-jobs [PATTERN...] List jobs\n"
6232 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6233 "Snapshot Commands:\n"
6234 " snapshot [NAME] Create a snapshot\n"
6235 " delete NAME... Remove one or more snapshots\n\n"
6236 "Environment Commands:\n"
6237 " show-environment Dump environment\n"
6238 " set-environment NAME=VALUE... Set one or more environment variables\n"
6239 " unset-environment NAME... Unset one or more environment variables\n"
6240 " import-environment [NAME...] Import all or some environment variables\n\n"
6241 "Manager Lifecycle Commands:\n"
6242 " daemon-reload Reload systemd manager configuration\n"
6243 " daemon-reexec Reexecute systemd manager\n\n"
6244 "System Commands:\n"
6245 " is-system-running Check whether system is fully running\n"
6246 " default Enter system default mode\n"
6247 " rescue Enter system rescue mode\n"
6248 " emergency Enter system emergency mode\n"
6249 " halt Shut down and halt the system\n"
6250 " poweroff Shut down and power-off the system\n"
6251 " reboot [ARG] Shut down and reboot the system\n"
6252 " kexec Shut down and reboot the system with kexec\n"
6253 " exit [EXIT_CODE] Request user instance or container exit\n"
6254 " switch-root ROOT [INIT] Change to a different root file system\n"
6255 " suspend Suspend the system\n"
6256 " hibernate Hibernate the system\n"
6257 " hybrid-sleep Hibernate and suspend the system\n",
6258 program_invocation_short_name
);
6261 static void halt_help(void) {
6262 printf("%s [OPTIONS...]%s\n\n"
6263 "%s the system.\n\n"
6264 " --help Show this help\n"
6265 " --halt Halt the machine\n"
6266 " -p --poweroff Switch off the machine\n"
6267 " --reboot Reboot the machine\n"
6268 " -f --force Force immediate halt/power-off/reboot\n"
6269 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6270 " -d --no-wtmp Don't write wtmp record\n"
6271 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6272 program_invocation_short_name
,
6273 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6274 arg_action
== ACTION_REBOOT
? "Reboot" :
6275 arg_action
== ACTION_POWEROFF
? "Power off" :
6279 static void shutdown_help(void) {
6280 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6281 "Shut down the system.\n\n"
6282 " --help Show this help\n"
6283 " -H --halt Halt the machine\n"
6284 " -P --poweroff Power-off the machine\n"
6285 " -r --reboot Reboot the machine\n"
6286 " -h Equivalent to --poweroff, overridden by --halt\n"
6287 " -k Don't halt/power-off/reboot, just send warnings\n"
6288 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6289 " -c Cancel a pending shutdown\n",
6290 program_invocation_short_name
);
6293 static void telinit_help(void) {
6294 printf("%s [OPTIONS...] {COMMAND}\n\n"
6295 "Send control commands to the init daemon.\n\n"
6296 " --help Show this help\n"
6297 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6299 " 0 Power-off the machine\n"
6300 " 6 Reboot the machine\n"
6301 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6302 " 1, s, S Enter rescue mode\n"
6303 " q, Q Reload init daemon configuration\n"
6304 " u, U Reexecute init daemon\n",
6305 program_invocation_short_name
);
6308 static void runlevel_help(void) {
6309 printf("%s [OPTIONS...]\n\n"
6310 "Prints the previous and current runlevel of the init system.\n\n"
6311 " --help Show this help\n",
6312 program_invocation_short_name
);
6315 static void help_types(void) {
6319 puts("Available unit types:");
6320 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6321 puts(unit_type_to_string(i
));
6324 static void help_states(void) {
6328 puts("Available unit load states:");
6329 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6330 puts(unit_load_state_to_string(i
));
6333 puts("\nAvailable unit active states:");
6334 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6335 puts(unit_active_state_to_string(i
));
6338 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6347 ARG_IGNORE_DEPENDENCIES
,
6359 ARG_NO_ASK_PASSWORD
,
6372 static const struct option options
[] = {
6373 { "help", no_argument
, NULL
, 'h' },
6374 { "version", no_argument
, NULL
, ARG_VERSION
},
6375 { "type", required_argument
, NULL
, 't' },
6376 { "property", required_argument
, NULL
, 'p' },
6377 { "all", no_argument
, NULL
, 'a' },
6378 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6379 { "after", no_argument
, NULL
, ARG_AFTER
},
6380 { "before", no_argument
, NULL
, ARG_BEFORE
},
6381 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6382 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6383 { "full", no_argument
, NULL
, 'l' },
6384 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6385 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6386 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6387 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6388 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6389 { "user", no_argument
, NULL
, ARG_USER
},
6390 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6391 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6392 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6393 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6394 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6395 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6396 { "quiet", no_argument
, NULL
, 'q' },
6397 { "root", required_argument
, NULL
, ARG_ROOT
},
6398 { "force", no_argument
, NULL
, ARG_FORCE
},
6399 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6400 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6401 { "signal", required_argument
, NULL
, 's' },
6402 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6403 { "host", required_argument
, NULL
, 'H' },
6404 { "machine", required_argument
, NULL
, 'M' },
6405 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6406 { "lines", required_argument
, NULL
, 'n' },
6407 { "output", required_argument
, NULL
, 'o' },
6408 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6409 { "state", required_argument
, NULL
, ARG_STATE
},
6410 { "recursive", no_argument
, NULL
, 'r' },
6411 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6412 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6413 { "now", no_argument
, NULL
, ARG_NOW
},
6414 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6423 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6424 arg_ask_password
= true;
6426 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6435 puts(PACKAGE_STRING
);
6436 puts(SYSTEMD_FEATURES
);
6440 const char *word
, *state
;
6443 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6444 _cleanup_free_
char *type
;
6446 type
= strndup(word
, size
);
6450 if (streq(type
, "help")) {
6455 if (unit_type_from_string(type
) >= 0) {
6456 if (strv_push(&arg_types
, type
))
6462 /* It's much nicer to use --state= for
6463 * load states, but let's support this
6464 * in --types= too for compatibility
6465 * with old versions */
6466 if (unit_load_state_from_string(optarg
) >= 0) {
6467 if (strv_push(&arg_states
, type
) < 0)
6473 log_error("Unknown unit type or load state '%s'.", type
);
6474 log_info("Use -t help to see a list of allowed values.");
6482 /* Make sure that if the empty property list
6483 was specified, we won't show any properties. */
6484 if (isempty(optarg
) && !arg_properties
) {
6485 arg_properties
= new0(char*, 1);
6486 if (!arg_properties
)
6489 const char *word
, *state
;
6492 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6495 prop
= strndup(word
, size
);
6499 if (strv_consume(&arg_properties
, prop
) < 0)
6504 /* If the user asked for a particular
6505 * property, show it to him, even if it is
6517 arg_dependency
= DEPENDENCY_REVERSE
;
6521 arg_dependency
= DEPENDENCY_AFTER
;
6525 arg_dependency
= DEPENDENCY_BEFORE
;
6528 case ARG_SHOW_TYPES
:
6529 arg_show_types
= true;
6533 arg_job_mode
= optarg
;
6537 arg_job_mode
= "fail";
6540 case ARG_IRREVERSIBLE
:
6541 arg_job_mode
= "replace-irreversibly";
6544 case ARG_IGNORE_DEPENDENCIES
:
6545 arg_job_mode
= "ignore-dependencies";
6549 arg_scope
= UNIT_FILE_USER
;
6553 arg_scope
= UNIT_FILE_SYSTEM
;
6557 arg_scope
= UNIT_FILE_GLOBAL
;
6561 arg_no_block
= true;
6565 arg_no_legend
= true;
6569 arg_no_pager
= true;
6585 if (strv_extend(&arg_states
, "failed") < 0)
6603 arg_no_reload
= true;
6607 arg_kill_who
= optarg
;
6611 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
6612 log_error("Failed to parse signal string %s.", optarg
);
6617 case ARG_NO_ASK_PASSWORD
:
6618 arg_ask_password
= false;
6622 arg_transport
= BUS_TRANSPORT_REMOTE
;
6627 arg_transport
= BUS_TRANSPORT_MACHINE
;
6636 if (safe_atou(optarg
, &arg_lines
) < 0) {
6637 log_error("Failed to parse lines '%s'", optarg
);
6643 arg_output
= output_mode_from_string(optarg
);
6644 if (arg_output
< 0) {
6645 log_error("Unknown output '%s'.", optarg
);
6651 arg_ignore_inhibitors
= true;
6658 case ARG_FIRMWARE_SETUP
:
6659 arg_firmware_setup
= true;
6663 const char *word
, *state
;
6666 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6669 s
= strndup(word
, size
);
6673 if (streq(s
, "help")) {
6678 if (strv_consume(&arg_states
, s
) < 0)
6685 if (geteuid() != 0) {
6686 log_error("--recursive requires root privileges.");
6690 arg_recursive
= true;
6693 case ARG_PRESET_MODE
:
6695 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6696 if (arg_preset_mode
< 0) {
6697 log_error("Failed to parse preset mode: %s.", optarg
);
6708 if (strv_extend(&arg_wall
, optarg
) < 0)
6716 assert_not_reached("Unhandled option");
6719 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6720 log_error("Cannot access user instance remotely.");
6727 static int halt_parse_argv(int argc
, char *argv
[]) {
6736 static const struct option options
[] = {
6737 { "help", no_argument
, NULL
, ARG_HELP
},
6738 { "halt", no_argument
, NULL
, ARG_HALT
},
6739 { "poweroff", no_argument
, NULL
, 'p' },
6740 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6741 { "force", no_argument
, NULL
, 'f' },
6742 { "wtmp-only", no_argument
, NULL
, 'w' },
6743 { "no-wtmp", no_argument
, NULL
, 'd' },
6744 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6753 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6754 if (runlevel
== '0' || runlevel
== '6')
6757 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6765 arg_action
= ACTION_HALT
;
6769 if (arg_action
!= ACTION_REBOOT
)
6770 arg_action
= ACTION_POWEROFF
;
6774 arg_action
= ACTION_REBOOT
;
6796 /* Compatibility nops */
6803 assert_not_reached("Unhandled option");
6806 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6807 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6810 } else if (optind
< argc
) {
6811 log_error("Too many arguments.");
6818 static int parse_time_spec(const char *t
, usec_t
*_u
) {
6822 if (streq(t
, "now"))
6824 else if (!strchr(t
, ':')) {
6827 if (safe_atou64(t
, &u
) < 0)
6830 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6839 hour
= strtol(t
, &e
, 10);
6840 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6843 minute
= strtol(e
+1, &e
, 10);
6844 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6847 n
= now(CLOCK_REALTIME
);
6848 s
= (time_t) (n
/ USEC_PER_SEC
);
6850 assert_se(localtime_r(&s
, &tm
));
6852 tm
.tm_hour
= (int) hour
;
6853 tm
.tm_min
= (int) minute
;
6856 assert_se(s
= mktime(&tm
));
6858 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6861 *_u
+= USEC_PER_DAY
;
6867 static int shutdown_parse_argv(int argc
, char *argv
[]) {
6874 static const struct option options
[] = {
6875 { "help", no_argument
, NULL
, ARG_HELP
},
6876 { "halt", no_argument
, NULL
, 'H' },
6877 { "poweroff", no_argument
, NULL
, 'P' },
6878 { "reboot", no_argument
, NULL
, 'r' },
6879 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
6880 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6889 while ((c
= getopt_long(argc
, argv
, "HPrhkKt:afFc", options
, NULL
)) >= 0)
6897 arg_action
= ACTION_HALT
;
6901 arg_action
= ACTION_POWEROFF
;
6906 arg_action
= ACTION_KEXEC
;
6908 arg_action
= ACTION_REBOOT
;
6912 arg_action
= ACTION_KEXEC
;
6916 if (arg_action
!= ACTION_HALT
)
6917 arg_action
= ACTION_POWEROFF
;
6932 /* Compatibility nops */
6936 arg_action
= ACTION_CANCEL_SHUTDOWN
;
6943 assert_not_reached("Unhandled option");
6946 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
6947 r
= parse_time_spec(argv
[optind
], &arg_when
);
6949 log_error("Failed to parse time specification: %s", argv
[optind
]);
6953 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
6955 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
6956 /* No time argument for shutdown cancel */
6957 arg_wall
= argv
+ optind
;
6958 else if (argc
> optind
+ 1)
6959 /* We skip the time argument */
6960 arg_wall
= argv
+ optind
+ 1;
6967 static int telinit_parse_argv(int argc
, char *argv
[]) {
6974 static const struct option options
[] = {
6975 { "help", no_argument
, NULL
, ARG_HELP
},
6976 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6980 static const struct {
6984 { '0', ACTION_POWEROFF
},
6985 { '6', ACTION_REBOOT
},
6986 { '1', ACTION_RESCUE
},
6987 { '2', ACTION_RUNLEVEL2
},
6988 { '3', ACTION_RUNLEVEL3
},
6989 { '4', ACTION_RUNLEVEL4
},
6990 { '5', ACTION_RUNLEVEL5
},
6991 { 's', ACTION_RESCUE
},
6992 { 'S', ACTION_RESCUE
},
6993 { 'q', ACTION_RELOAD
},
6994 { 'Q', ACTION_RELOAD
},
6995 { 'u', ACTION_REEXEC
},
6996 { 'U', ACTION_REEXEC
}
7005 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7020 assert_not_reached("Unhandled option");
7023 if (optind
>= argc
) {
7024 log_error("%s: required argument missing.",
7025 program_invocation_short_name
);
7029 if (optind
+ 1 < argc
) {
7030 log_error("Too many arguments.");
7034 if (strlen(argv
[optind
]) != 1) {
7035 log_error("Expected single character argument.");
7039 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7040 if (table
[i
].from
== argv
[optind
][0])
7043 if (i
>= ELEMENTSOF(table
)) {
7044 log_error("Unknown command '%s'.", argv
[optind
]);
7048 arg_action
= table
[i
].to
;
7055 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7061 static const struct option options
[] = {
7062 { "help", no_argument
, NULL
, ARG_HELP
},
7071 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7082 assert_not_reached("Unhandled option");
7085 if (optind
< argc
) {
7086 log_error("Too many arguments.");
7093 static int parse_argv(int argc
, char *argv
[]) {
7097 if (program_invocation_short_name
) {
7099 if (strstr(program_invocation_short_name
, "halt")) {
7100 arg_action
= ACTION_HALT
;
7101 return halt_parse_argv(argc
, argv
);
7102 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7103 arg_action
= ACTION_POWEROFF
;
7104 return halt_parse_argv(argc
, argv
);
7105 } else if (strstr(program_invocation_short_name
, "reboot")) {
7107 arg_action
= ACTION_KEXEC
;
7109 arg_action
= ACTION_REBOOT
;
7110 return halt_parse_argv(argc
, argv
);
7111 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7112 arg_action
= ACTION_POWEROFF
;
7113 return shutdown_parse_argv(argc
, argv
);
7114 } else if (strstr(program_invocation_short_name
, "init")) {
7116 if (sd_booted() > 0) {
7117 arg_action
= _ACTION_INVALID
;
7118 return telinit_parse_argv(argc
, argv
);
7120 /* Hmm, so some other init system is
7121 * running, we need to forward this
7122 * request to it. For now we simply
7123 * guess that it is Upstart. */
7125 execv(TELINIT
, argv
);
7127 log_error("Couldn't find an alternative telinit implementation to spawn.");
7131 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7132 arg_action
= ACTION_RUNLEVEL
;
7133 return runlevel_parse_argv(argc
, argv
);
7137 arg_action
= ACTION_SYSTEMCTL
;
7138 return systemctl_parse_argv(argc
, argv
);
7141 _pure_
static int action_to_runlevel(void) {
7143 static const char table
[_ACTION_MAX
] = {
7144 [ACTION_HALT
] = '0',
7145 [ACTION_POWEROFF
] = '0',
7146 [ACTION_REBOOT
] = '6',
7147 [ACTION_RUNLEVEL2
] = '2',
7148 [ACTION_RUNLEVEL3
] = '3',
7149 [ACTION_RUNLEVEL4
] = '4',
7150 [ACTION_RUNLEVEL5
] = '5',
7151 [ACTION_RESCUE
] = '1'
7154 assert(arg_action
< _ACTION_MAX
);
7156 return table
[arg_action
];
7159 static int talk_initctl(void) {
7161 struct init_request request
= {
7162 .magic
= INIT_MAGIC
,
7164 .cmd
= INIT_CMD_RUNLVL
7167 _cleanup_close_
int fd
= -1;
7171 rl
= action_to_runlevel();
7175 request
.runlevel
= rl
;
7177 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7179 if (errno
== ENOENT
)
7182 log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7186 r
= loop_write(fd
, &request
, sizeof(request
), false);
7188 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7193 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
7195 static const struct {
7203 int (* const dispatch
)(sd_bus
*bus
, char **args
);
7209 { "list-units", MORE
, 0, list_units
},
7210 { "list-unit-files", MORE
, 1, list_unit_files
, NOBUS
},
7211 { "list-sockets", MORE
, 1, list_sockets
},
7212 { "list-timers", MORE
, 1, list_timers
},
7213 { "list-jobs", MORE
, 1, list_jobs
},
7214 { "list-machines", MORE
, 1, list_machines
},
7215 { "clear-jobs", EQUAL
, 1, daemon_reload
},
7216 { "cancel", MORE
, 2, cancel_job
},
7217 { "start", MORE
, 2, start_unit
},
7218 { "stop", MORE
, 2, start_unit
},
7219 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7220 { "reload", MORE
, 2, start_unit
},
7221 { "restart", MORE
, 2, start_unit
},
7222 { "try-restart", MORE
, 2, start_unit
},
7223 { "reload-or-restart", MORE
, 2, start_unit
},
7224 { "reload-or-try-restart", MORE
, 2, start_unit
},
7225 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
7226 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7227 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
7228 { "isolate", EQUAL
, 2, start_unit
},
7229 { "kill", MORE
, 2, kill_unit
},
7230 { "is-active", MORE
, 2, check_unit_active
},
7231 { "check", MORE
, 2, check_unit_active
},
7232 { "is-failed", MORE
, 2, check_unit_failed
},
7233 { "show", MORE
, 1, show
},
7234 { "cat", MORE
, 2, cat
, NOBUS
},
7235 { "status", MORE
, 1, show
},
7236 { "help", MORE
, 2, show
},
7237 { "snapshot", LESS
, 2, snapshot
},
7238 { "delete", MORE
, 2, delete_snapshot
},
7239 { "daemon-reload", EQUAL
, 1, daemon_reload
},
7240 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
7241 { "show-environment", EQUAL
, 1, show_environment
},
7242 { "set-environment", MORE
, 2, set_environment
},
7243 { "unset-environment", MORE
, 2, set_environment
},
7244 { "import-environment", MORE
, 1, import_environment
},
7245 { "halt", EQUAL
, 1, start_special
, FORCE
},
7246 { "poweroff", EQUAL
, 1, start_special
, FORCE
},
7247 { "reboot", MORE
, 1, start_special
, FORCE
},
7248 { "kexec", EQUAL
, 1, start_special
},
7249 { "suspend", EQUAL
, 1, start_special
},
7250 { "hibernate", EQUAL
, 1, start_special
},
7251 { "hybrid-sleep", EQUAL
, 1, start_special
},
7252 { "default", EQUAL
, 1, start_special
},
7253 { "rescue", EQUAL
, 1, start_special
},
7254 { "emergency", EQUAL
, 1, start_special
},
7255 { "exit", LESS
, 2, start_special
},
7256 { "reset-failed", MORE
, 1, reset_failed
},
7257 { "enable", MORE
, 2, enable_unit
, NOBUS
},
7258 { "disable", MORE
, 2, enable_unit
, NOBUS
},
7259 { "is-enabled", MORE
, 2, unit_is_enabled
, NOBUS
},
7260 { "reenable", MORE
, 2, enable_unit
, NOBUS
},
7261 { "preset", MORE
, 2, enable_unit
, NOBUS
},
7262 { "preset-all", EQUAL
, 1, preset_all
, NOBUS
},
7263 { "mask", MORE
, 2, enable_unit
, NOBUS
},
7264 { "unmask", MORE
, 2, enable_unit
, NOBUS
},
7265 { "link", MORE
, 2, enable_unit
, NOBUS
},
7266 { "switch-root", MORE
, 2, switch_root
},
7267 { "list-dependencies", LESS
, 2, list_dependencies
},
7268 { "set-default", EQUAL
, 2, set_default
, NOBUS
},
7269 { "get-default", EQUAL
, 1, get_default
, NOBUS
},
7270 { "set-property", MORE
, 3, set_property
},
7271 { "is-system-running", EQUAL
, 1, is_system_running
},
7272 { "add-wants", MORE
, 3, add_dependency
, NOBUS
},
7273 { "add-requires", MORE
, 3, add_dependency
, NOBUS
},
7274 { "edit", MORE
, 2, edit
, NOBUS
},
7283 left
= argc
- optind
;
7285 /* Special rule: no arguments (left == 0) means "list-units" */
7287 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
7288 log_error("This command expects one or more "
7289 "unit names. Did you mean --help?");
7293 for (; verb
->verb
; verb
++)
7294 if (streq(argv
[optind
], verb
->verb
))
7297 log_error("Unknown operation '%s'.", argv
[optind
]);
7302 switch (verb
->argc_cmp
) {
7305 if (left
!= verb
->argc
) {
7306 log_error("Invalid number of arguments.");
7313 if (left
< verb
->argc
) {
7314 log_error("Too few arguments.");
7321 if (left
> verb
->argc
) {
7322 log_error("Too many arguments.");
7329 assert_not_reached("Unknown comparison operator.");
7332 /* Require a bus connection for all operations but
7334 if (verb
->bus
== NOBUS
) {
7335 if (!bus
&& !avoid_bus()) {
7336 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7341 if (running_in_chroot() > 0) {
7342 log_info("Running in chroot, ignoring request.");
7346 if ((verb
->bus
!= FORCE
|| arg_force
<= 0) && !bus
) {
7347 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7352 return verb
->dispatch(bus
, argv
+ optind
);
7355 static int reload_with_fallback(sd_bus
*bus
) {
7358 /* First, try systemd via D-Bus. */
7359 if (daemon_reload(bus
, NULL
) >= 0)
7363 /* Nothing else worked, so let's try signals */
7364 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7366 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7367 return log_error_errno(errno
, "kill() failed: %m");
7372 static int start_with_fallback(sd_bus
*bus
) {
7375 /* First, try systemd via D-Bus. */
7376 if (start_unit(bus
, NULL
) >= 0)
7380 /* Nothing else worked, so let's try
7382 if (talk_initctl() > 0)
7385 log_error("Failed to talk to init daemon.");
7389 warn_wall(arg_action
);
7393 static int halt_now(enum action a
) {
7395 /* The kernel will automaticall flush ATA disks and suchlike
7396 * on reboot(), but the file systems need to be synce'd
7397 * explicitly in advance. */
7400 /* Make sure C-A-D is handled by the kernel from this point
7402 reboot(RB_ENABLE_CAD
);
7407 log_info("Halting.");
7408 reboot(RB_HALT_SYSTEM
);
7411 case ACTION_POWEROFF
:
7412 log_info("Powering off.");
7413 reboot(RB_POWER_OFF
);
7417 case ACTION_REBOOT
: {
7418 _cleanup_free_
char *param
= NULL
;
7420 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7421 log_info("Rebooting with argument '%s'.", param
);
7422 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
7423 LINUX_REBOOT_CMD_RESTART2
, param
);
7426 log_info("Rebooting.");
7427 reboot(RB_AUTOBOOT
);
7432 assert_not_reached("Unknown action.");
7436 static int halt_main(sd_bus
*bus
) {
7439 r
= check_inhibitors(bus
, arg_action
);
7443 if (geteuid() != 0) {
7447 log_error("Must be root.");
7451 /* Try logind if we are a normal user and no special
7452 * mode applies. Maybe PolicyKit allows us to shutdown
7454 if (IN_SET(arg_action
,
7457 r
= reboot_with_logind(bus
, arg_action
);
7460 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7461 /* requested operation is not supported or already in progress */
7463 /* on all other errors, try low-level operation */
7468 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7469 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7470 _cleanup_free_
char *m
= NULL
;
7473 assert(geteuid() == 0);
7476 log_error("Unable to perform operation without bus connection.");
7480 r
= sd_bus_open_system(&b
);
7482 return log_error_errno(r
, "Unable to open system bus: %m");
7484 m
= strv_join(arg_wall
, " ");
7488 r
= sd_bus_call_method(
7490 "org.freedesktop.login1",
7491 "/org/freedesktop/login1",
7492 "org.freedesktop.login1.Manager",
7501 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
7502 bus_error_message(&error
, r
));
7503 sd_bus_error_free(&error
);
7506 switch (arg_action
) {
7510 case ACTION_POWEROFF
:
7511 action
= "poweroff";
7522 action
= strjoina("dry-", action
);
7524 r
= sd_bus_call_method(
7526 "org.freedesktop.login1",
7527 "/org/freedesktop/login1",
7528 "org.freedesktop.login1.Manager",
7536 log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s",
7537 bus_error_message(&error
, r
));
7539 char date
[FORMAT_TIMESTAMP_MAX
];
7541 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7542 format_timestamp(date
, sizeof(date
), arg_when
));
7547 if (!arg_dry
&& !arg_force
)
7548 return start_with_fallback(bus
);
7550 assert(geteuid() == 0);
7553 if (sd_booted() > 0)
7554 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7556 r
= utmp_put_shutdown();
7558 log_warning_errno(r
, "Failed to write utmp record: %m");
7565 r
= halt_now(arg_action
);
7566 log_error_errno(r
, "Failed to reboot: %m");
7571 static int runlevel_main(void) {
7572 int r
, runlevel
, previous
;
7574 r
= utmp_get_runlevel(&runlevel
, &previous
);
7581 previous
<= 0 ? 'N' : previous
,
7582 runlevel
<= 0 ? 'N' : runlevel
);
7587 int main(int argc
, char*argv
[]) {
7588 _cleanup_bus_flush_close_unref_ sd_bus
*bus
= NULL
;
7591 setlocale(LC_ALL
, "");
7592 log_parse_environment();
7595 /* Explicitly not on_tty() to avoid setting cached value.
7596 * This becomes relevant for piping output which might be
7598 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7600 r
= parse_argv(argc
, argv
);
7604 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7605 * let's shortcut this */
7606 if (arg_action
== ACTION_RUNLEVEL
) {
7607 r
= runlevel_main();
7611 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7612 log_info("Running in chroot, ignoring request.");
7618 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
7621 sd_bus_set_allow_interactive_authorization(bus
, arg_ask_password
);
7623 /* systemctl_main() will print an error message for the bus
7624 * connection, but only if it needs to */
7626 switch (arg_action
) {
7628 case ACTION_SYSTEMCTL
:
7629 r
= systemctl_main(bus
, argc
, argv
, r
);
7633 case ACTION_POWEROFF
:
7639 case ACTION_RUNLEVEL2
:
7640 case ACTION_RUNLEVEL3
:
7641 case ACTION_RUNLEVEL4
:
7642 case ACTION_RUNLEVEL5
:
7644 case ACTION_EMERGENCY
:
7645 case ACTION_DEFAULT
:
7646 r
= start_with_fallback(bus
);
7651 r
= reload_with_fallback(bus
);
7654 case ACTION_CANCEL_SHUTDOWN
: {
7655 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7656 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7657 _cleanup_free_
char *m
= NULL
;
7660 log_error("Unable to perform operation without bus connection.");
7664 r
= sd_bus_open_system(&b
);
7666 return log_error_errno(r
, "Unable to open system bus: %m");
7669 m
= strv_join(arg_wall
, " ");
7676 r
= sd_bus_call_method(
7678 "org.freedesktop.login1",
7679 "/org/freedesktop/login1",
7680 "org.freedesktop.login1.Manager",
7689 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
7690 bus_error_message(&error
, r
));
7691 sd_bus_error_free(&error
);
7694 r
= sd_bus_call_method(
7696 "org.freedesktop.login1",
7697 "/org/freedesktop/login1",
7698 "org.freedesktop.login1.Manager",
7699 "CancelScheduledShutdown",
7703 log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s",
7704 bus_error_message(&error
, r
));
7708 case ACTION_RUNLEVEL
:
7709 case _ACTION_INVALID
:
7711 assert_not_reached("Unknown action");
7716 ask_password_agent_close();
7717 polkit_agent_close();
7719 strv_free(arg_types
);
7720 strv_free(arg_states
);
7721 strv_free(arg_properties
);
7723 sd_bus_default_flush_close();
7725 return r
< 0 ? EXIT_FAILURE
: r
;