2 This file is part of systemd.
4 Copyright 2010 Lennart Poettering
5 Copyright 2013 Marc-Antoine Perennou
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/reboot.h>
30 #include <sys/reboot.h>
31 #include <sys/socket.h>
35 #include "sd-daemon.h"
38 #include "alloc-util.h"
39 #include "bus-common-errors.h"
40 #include "bus-error.h"
41 #include "bus-message.h"
42 #include "bus-unit-util.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
50 #include "exit-status.h"
53 #include "format-util.h"
55 #include "glob-util.h"
56 #include "hostname-util.h"
61 #include "locale-util.h"
63 #include "logs-show.h"
67 #include "parse-util.h"
68 #include "path-lookup.h"
69 #include "path-util.h"
70 #include "process-util.h"
71 #include "rlimit-util.h"
74 #include "signal-util.h"
75 #include "socket-util.h"
76 #include "spawn-ask-password-agent.h"
77 #include "spawn-polkit-agent.h"
79 #include "stat-util.h"
81 #include "terminal-util.h"
82 #include "unit-name.h"
83 #include "user-util.h"
85 #include "utmp-wtmp.h"
89 /* The init script exit status codes
90 0 program is running or service is OK
91 1 program is dead and /var/run pid file exists
92 2 program is dead and /var/lock lock file exists
93 3 program is not running
94 4 program or service status is unknown
95 5-99 reserved for future LSB use
96 100-149 reserved for distribution use
97 150-199 reserved for application use
101 EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
= 0,
102 EXIT_PROGRAM_DEAD_AND_PID_EXISTS
= 1,
103 EXIT_PROGRAM_DEAD_AND_LOCK_FILE_EXISTS
= 2,
104 EXIT_PROGRAM_NOT_RUNNING
= 3,
105 EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
= 4,
108 static char **arg_types
= NULL
;
109 static char **arg_states
= NULL
;
110 static char **arg_properties
= NULL
;
111 static bool arg_all
= false;
112 static enum dependency
{
118 } arg_dependency
= DEPENDENCY_FORWARD
;
119 static const char *arg_job_mode
= "replace";
120 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
121 static bool arg_wait
= false;
122 static bool arg_no_block
= false;
123 static bool arg_no_legend
= false;
124 static bool arg_no_pager
= false;
125 static bool arg_no_wtmp
= false;
126 static bool arg_no_sync
= false;
127 static bool arg_no_wall
= false;
128 static bool arg_no_reload
= false;
129 static bool arg_value
= false;
130 static bool arg_show_types
= false;
131 static bool arg_ignore_inhibitors
= false;
132 static bool arg_dry
= false;
133 static bool arg_quiet
= false;
134 static bool arg_full
= false;
135 static bool arg_recursive
= false;
136 static int arg_force
= 0;
137 static bool arg_ask_password
= false;
138 static bool arg_runtime
= false;
139 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
140 static char **arg_wall
= NULL
;
141 static const char *arg_kill_who
= NULL
;
142 static int arg_signal
= SIGTERM
;
143 static char *arg_root
= NULL
;
144 static usec_t arg_when
= 0;
145 static char *argv_cmdline
= NULL
;
167 ACTION_CANCEL_SHUTDOWN
,
169 } arg_action
= ACTION_SYSTEMCTL
;
170 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
171 static const char *arg_host
= NULL
;
172 static unsigned arg_lines
= 10;
173 static OutputMode arg_output
= OUTPUT_SHORT
;
174 static bool arg_plain
= false;
175 static bool arg_firmware_setup
= false;
176 static bool arg_now
= false;
177 static bool arg_jobs_before
= false;
178 static bool arg_jobs_after
= false;
180 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
181 static int trivial_method(int argc
, char *argv
[], void *userdata
);
182 static int halt_now(enum action a
);
183 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
185 static bool original_stdout_is_tty
;
187 typedef enum BusFocus
{
188 BUS_FULL
, /* The full bus indicated via --system or --user */
189 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
193 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
195 static UnitFileFlags
args_to_flags(void) {
196 return (arg_runtime
? UNIT_FILE_RUNTIME
: 0) |
197 (arg_force
? UNIT_FILE_FORCE
: 0);
200 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
203 assert(focus
< _BUS_FOCUS_MAX
);
206 /* We only go directly to the manager, if we are using a local transport */
207 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
210 if (getenv_bool("SYSTEMCTL_FORCE_BUS") > 0)
213 if (!busses
[focus
]) {
216 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
218 if (focus
== BUS_MANAGER
)
219 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
221 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
223 return log_error_errno(r
, "Failed to connect to bus: %m");
225 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
228 *ret
= busses
[focus
];
232 static void release_busses(void) {
235 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
236 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
239 static int map_string_no_copy(sd_bus
*bus
, const char *member
, sd_bus_message
*m
, sd_bus_error
*error
, void *userdata
) {
241 const char **p
= userdata
;
244 r
= sd_bus_message_read_basic(m
, SD_BUS_TYPE_STRING
, &s
);
254 static void ask_password_agent_open_if_enabled(void) {
256 /* Open the password agent as a child process if necessary */
258 if (!arg_ask_password
)
261 if (arg_scope
!= UNIT_FILE_SYSTEM
)
264 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
267 ask_password_agent_open();
270 static void polkit_agent_open_if_enabled(void) {
272 /* Open the polkit agent as a child process if necessary */
274 if (!arg_ask_password
)
277 if (arg_scope
!= UNIT_FILE_SYSTEM
)
280 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
286 static OutputFlags
get_output_flags(void) {
288 arg_all
* OUTPUT_SHOW_ALL
|
289 arg_full
* OUTPUT_FULL_WIDTH
|
290 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
291 colors_enabled() * OUTPUT_COLOR
|
292 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
295 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
298 if (!sd_bus_error_is_set(error
))
301 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
302 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
303 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
304 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
305 return EXIT_NOPERMISSION
;
307 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
308 return EXIT_NOTINSTALLED
;
310 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
311 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
312 return EXIT_NOTIMPLEMENTED
;
314 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
315 return EXIT_NOTCONFIGURED
;
323 static bool install_client_side(void) {
325 /* Decides when to execute enable/disable/... operations
326 * client-side rather than server-side. */
328 if (running_in_chroot() > 0)
331 if (sd_booted() <= 0)
334 if (!isempty(arg_root
))
337 if (arg_scope
== UNIT_FILE_GLOBAL
)
340 /* Unsupported environment variable, mostly for debugging purposes */
341 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
347 static int compare_unit_info(const void *a
, const void *b
) {
348 const UnitInfo
*u
= a
, *v
= b
;
352 /* First, order by machine */
353 if (!u
->machine
&& v
->machine
)
355 if (u
->machine
&& !v
->machine
)
357 if (u
->machine
&& v
->machine
) {
358 r
= strcasecmp(u
->machine
, v
->machine
);
363 /* Second, order by unit type */
364 d1
= strrchr(u
->id
, '.');
365 d2
= strrchr(v
->id
, '.');
367 r
= strcasecmp(d1
, d2
);
372 /* Third, order by name */
373 return strcasecmp(u
->id
, v
->id
);
376 static const char* unit_type_suffix(const char *name
) {
379 dot
= strrchr(name
, '.');
386 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
389 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
392 if (arg_types
&& !strv_find(arg_types
, unit_type_suffix(u
->id
)))
398 /* Note that '--all' is not purely a state filter, but also a
399 * filter that hides units that "follow" other units (which is
400 * used for device units that appear under different names). */
401 if (!isempty(u
->following
))
404 if (!strv_isempty(arg_states
))
407 /* By default show all units except the ones in inactive
408 * state and with no pending job */
412 if (streq(u
->active_state
, "inactive"))
418 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
419 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
, max_desc_len
;
421 unsigned n_shown
= 0;
424 max_id_len
= strlen("UNIT");
425 load_len
= strlen("LOAD");
426 active_len
= strlen("ACTIVE");
427 sub_len
= strlen("SUB");
428 job_len
= strlen("JOB");
429 max_desc_len
= strlen("DESCRIPTION");
431 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
432 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
433 load_len
= MAX(load_len
, strlen(u
->load_state
));
434 active_len
= MAX(active_len
, strlen(u
->active_state
));
435 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
436 max_desc_len
= MAX(max_desc_len
, strlen(u
->description
));
438 if (u
->job_id
!= 0) {
439 job_len
= MAX(job_len
, strlen(u
->job_type
));
443 if (!arg_no_legend
&&
444 (streq(u
->active_state
, "failed") ||
445 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
449 if (!arg_full
&& original_stdout_is_tty
) {
452 id_len
= MIN(max_id_len
, 25u); /* as much as it needs, but at most 25 for now */
453 basic_len
= circle_len
+ 1 + id_len
+ 1 + load_len
+ 1 + active_len
+ 1 + sub_len
+ 1;
456 basic_len
+= job_len
+ 1;
458 if (basic_len
< (unsigned) columns()) {
459 unsigned extra_len
, incr
;
460 extra_len
= columns() - basic_len
;
462 /* Either UNIT already got 25, or is fully satisfied.
463 * Grant up to 25 to DESC now. */
464 incr
= MIN(extra_len
, 25u);
468 /* Of the remainder give as much as the ID needs to the ID, and give the rest to the
469 * description but not more than it needs. */
471 incr
= MIN(max_id_len
- id_len
, extra_len
);
473 desc_len
+= MIN(extra_len
- incr
, max_desc_len
- desc_len
);
479 desc_len
= max_desc_len
;
482 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
483 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
484 const char *on_underline
= "", *off_underline
= "";
485 const char *on_loaded
= "", *off_loaded
= "";
486 const char *on_active
= "", *off_active
= "";
487 const char *on_circle
= "", *off_circle
= "";
489 bool circle
= false, underline
= false;
491 if (!n_shown
&& !arg_no_legend
) {
496 printf("%s%-*s %-*s %-*s %-*s ",
500 active_len
, "ACTIVE",
504 printf("%-*s ", job_len
, "JOB");
508 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
515 if (u
+ 1 < unit_infos
+ c
&&
516 !streq(unit_type_suffix(u
->id
), unit_type_suffix((u
+ 1)->id
))) {
517 on_underline
= ansi_underline();
518 off_underline
= ansi_normal();
522 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
523 on_circle
= ansi_highlight_yellow();
524 off_circle
= ansi_normal();
526 on_loaded
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
527 off_loaded
= underline
? on_underline
: ansi_normal();
528 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
529 on_circle
= ansi_highlight_red();
530 off_circle
= ansi_normal();
532 on_active
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
533 off_active
= underline
? on_underline
: ansi_normal();
537 j
= strjoin(u
->machine
, ":", u
->id
);
546 e
= ellipsize(id
, id_len
, 33);
554 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
556 printf("%s%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
558 on_active
, id_len
, id
, off_active
,
559 on_loaded
, load_len
, u
->load_state
, off_loaded
,
560 on_active
, active_len
, u
->active_state
,
561 sub_len
, u
->sub_state
, off_active
,
562 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
566 !arg_full
&& arg_no_pager
? (int) desc_len
: -1,
571 if (!arg_no_legend
) {
572 const char *on
, *off
;
576 "LOAD = Reflects whether the unit definition was properly loaded.\n"
577 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
578 "SUB = The low-level unit activation state, values depend on unit type.");
579 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
580 on
= ansi_highlight();
583 on
= ansi_highlight_red();
588 printf("%s%u loaded units listed.%s\n"
589 "To show all installed unit files use 'systemctl list-unit-files'.\n",
592 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
593 "To show all installed unit files use 'systemctl list-unit-files'.\n",
600 static int get_unit_list(
604 UnitInfo
**unit_infos
,
606 sd_bus_message
**_reply
) {
608 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
609 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
610 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
614 bool fallback
= false;
620 r
= sd_bus_message_new_method_call(
623 "org.freedesktop.systemd1",
624 "/org/freedesktop/systemd1",
625 "org.freedesktop.systemd1.Manager",
626 "ListUnitsByPatterns");
628 return bus_log_create_error(r
);
630 r
= sd_bus_message_append_strv(m
, arg_states
);
632 return bus_log_create_error(r
);
634 r
= sd_bus_message_append_strv(m
, patterns
);
636 return bus_log_create_error(r
);
638 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
639 if (r
< 0 && (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
) ||
640 sd_bus_error_has_name(&error
, SD_BUS_ERROR_ACCESS_DENIED
))) {
641 /* Fallback to legacy ListUnitsFiltered method */
643 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
644 m
= sd_bus_message_unref(m
);
645 sd_bus_error_free(&error
);
647 r
= sd_bus_message_new_method_call(
650 "org.freedesktop.systemd1",
651 "/org/freedesktop/systemd1",
652 "org.freedesktop.systemd1.Manager",
653 "ListUnitsFiltered");
655 return bus_log_create_error(r
);
657 r
= sd_bus_message_append_strv(m
, arg_states
);
659 return bus_log_create_error(r
);
661 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
664 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
666 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
668 return bus_log_parse_error(r
);
670 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
673 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
676 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
679 (*unit_infos
)[c
++] = u
;
682 return bus_log_parse_error(r
);
684 r
= sd_bus_message_exit_container(reply
);
686 return bus_log_parse_error(r
);
694 static void message_set_freep(Set
**set
) {
697 while ((m
= set_steal_first(*set
)))
698 sd_bus_message_unref(m
);
703 static int get_unit_list_recursive(
706 UnitInfo
**_unit_infos
,
710 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
711 _cleanup_(message_set_freep
) Set
*replies
;
712 sd_bus_message
*reply
;
720 replies
= set_new(NULL
);
724 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
728 r
= set_put(replies
, reply
);
730 sd_bus_message_unref(reply
);
735 _cleanup_strv_free_
char **machines
= NULL
;
738 r
= sd_get_machine_names(&machines
);
740 return log_error_errno(r
, "Failed to get machine names: %m");
742 STRV_FOREACH(i
, machines
) {
743 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
746 r
= sd_bus_open_system_machine(&container
, *i
);
748 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
752 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
758 r
= set_put(replies
, reply
);
760 sd_bus_message_unref(reply
);
765 *_machines
= machines
;
770 *_unit_infos
= unit_infos
;
779 static int list_units(int argc
, char *argv
[], void *userdata
) {
780 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
781 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
782 _cleanup_strv_free_
char **machines
= NULL
;
786 r
= acquire_bus(BUS_MANAGER
, &bus
);
790 pager_open(arg_no_pager
, false);
792 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
796 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
797 return output_units_list(unit_infos
, r
);
800 static int get_triggered_units(
805 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
812 r
= sd_bus_get_property_strv(
814 "org.freedesktop.systemd1",
816 "org.freedesktop.systemd1.Unit",
821 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
826 static int get_listening(
828 const char* unit_path
,
831 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
832 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
833 const char *type
, *path
;
836 r
= sd_bus_get_property(
838 "org.freedesktop.systemd1",
840 "org.freedesktop.systemd1.Socket",
846 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
848 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
850 return bus_log_parse_error(r
);
852 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
854 r
= strv_extend(listening
, type
);
858 r
= strv_extend(listening
, path
);
865 return bus_log_parse_error(r
);
867 r
= sd_bus_message_exit_container(reply
);
869 return bus_log_parse_error(r
);
881 /* Note: triggered is a list here, although it almost certainly
882 * will always be one unit. Nevertheless, dbus API allows for multiple
883 * values, so let's follow that. */
886 /* The strv above is shared. free is set only in the first one. */
890 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
896 if (!a
->machine
&& b
->machine
)
898 if (a
->machine
&& !b
->machine
)
900 if (a
->machine
&& b
->machine
) {
901 o
= strcasecmp(a
->machine
, b
->machine
);
906 o
= strcmp(a
->path
, b
->path
);
908 o
= strcmp(a
->type
, b
->type
);
913 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
914 struct socket_info
*s
;
915 unsigned pathlen
= strlen("LISTEN"),
916 typelen
= strlen("TYPE") * arg_show_types
,
917 socklen
= strlen("UNIT"),
918 servlen
= strlen("ACTIVATES");
919 const char *on
, *off
;
921 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
925 socklen
= MAX(socklen
, strlen(s
->id
));
927 typelen
= MAX(typelen
, strlen(s
->type
));
928 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
930 STRV_FOREACH(a
, s
->triggered
)
931 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
932 servlen
= MAX(servlen
, tmp
);
937 printf("%-*s %-*.*s%-*s %s\n",
939 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
943 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
944 _cleanup_free_
char *j
= NULL
;
949 j
= strjoin(s
->machine
, ":", s
->path
);
957 printf("%-*s %-*s %-*s",
958 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
961 pathlen
, path
, socklen
, s
->id
);
962 STRV_FOREACH(a
, s
->triggered
)
964 a
== s
->triggered
? "" : ",", *a
);
968 on
= ansi_highlight();
973 on
= ansi_highlight_red();
977 if (!arg_no_legend
) {
978 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
980 printf("Pass --all to see loaded but inactive sockets, too.\n");
986 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
987 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
988 _cleanup_strv_free_
char **machines
= NULL
;
989 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
990 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
992 struct socket_info
*s
;
998 r
= acquire_bus(BUS_MANAGER
, &bus
);
1002 pager_open(arg_no_pager
, false);
1004 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1008 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1009 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
1012 if (!endswith(u
->id
, ".socket"))
1015 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1019 c
= get_listening(bus
, u
->unit_path
, &listening
);
1025 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
1030 for (i
= 0; i
< c
; i
++)
1031 socket_infos
[cs
+ i
] = (struct socket_info
) {
1032 .machine
= u
->machine
,
1034 .type
= listening
[i
*2],
1035 .path
= listening
[i
*2 + 1],
1036 .triggered
= triggered
,
1037 .own_triggered
= i
==0,
1040 /* from this point on we will cleanup those socket_infos */
1043 listening
= triggered
= NULL
; /* avoid cleanup */
1046 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
1047 (__compar_fn_t
) socket_info_compare
);
1049 output_sockets_list(socket_infos
, cs
);
1052 assert(cs
== 0 || socket_infos
);
1053 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
1056 if (s
->own_triggered
)
1057 strv_free(s
->triggered
);
1063 static int get_next_elapse(
1066 dual_timestamp
*next
) {
1068 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1076 r
= sd_bus_get_property_trivial(
1078 "org.freedesktop.systemd1",
1080 "org.freedesktop.systemd1.Timer",
1081 "NextElapseUSecMonotonic",
1086 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1088 r
= sd_bus_get_property_trivial(
1090 "org.freedesktop.systemd1",
1092 "org.freedesktop.systemd1.Timer",
1093 "NextElapseUSecRealtime",
1098 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1104 static int get_last_trigger(
1109 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1116 r
= sd_bus_get_property_trivial(
1118 "org.freedesktop.systemd1",
1120 "org.freedesktop.systemd1.Timer",
1126 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1132 const char* machine
;
1135 usec_t last_trigger
;
1139 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1145 if (!a
->machine
&& b
->machine
)
1147 if (a
->machine
&& !b
->machine
)
1149 if (a
->machine
&& b
->machine
) {
1150 o
= strcasecmp(a
->machine
, b
->machine
);
1155 if (a
->next_elapse
< b
->next_elapse
)
1157 if (a
->next_elapse
> b
->next_elapse
)
1160 return strcmp(a
->id
, b
->id
);
1163 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1164 struct timer_info
*t
;
1166 nextlen
= strlen("NEXT"),
1167 leftlen
= strlen("LEFT"),
1168 lastlen
= strlen("LAST"),
1169 passedlen
= strlen("PASSED"),
1170 unitlen
= strlen("UNIT"),
1171 activatelen
= strlen("ACTIVATES");
1173 const char *on
, *off
;
1175 assert(timer_infos
|| n
== 0);
1177 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1181 if (t
->next_elapse
> 0) {
1182 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1184 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1185 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1187 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1188 leftlen
= MAX(leftlen
, strlen(trel
));
1191 if (t
->last_trigger
> 0) {
1192 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1194 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1195 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1197 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1198 passedlen
= MAX(passedlen
, strlen(trel
));
1201 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1203 STRV_FOREACH(a
, t
->triggered
)
1204 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1206 activatelen
= MAX(activatelen
, ul
);
1211 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1215 passedlen
, "PASSED",
1219 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1220 _cleanup_free_
char *j
= NULL
;
1222 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1223 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1226 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1227 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1229 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1230 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1233 j
= strjoin(t
->machine
, ":", t
->id
);
1240 printf("%-*s %-*s %-*s %-*s %-*s",
1241 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1243 STRV_FOREACH(a
, t
->triggered
)
1245 a
== t
->triggered
? "" : ",", *a
);
1249 on
= ansi_highlight();
1250 off
= ansi_normal();
1254 on
= ansi_highlight_red();
1255 off
= ansi_normal();
1258 if (!arg_no_legend
) {
1259 printf("%s%u timers listed.%s\n", on
, n
, off
);
1261 printf("Pass --all to see loaded but inactive timers, too.\n");
1267 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1273 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1276 if (next
->monotonic
> nw
->monotonic
)
1277 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1279 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1281 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1282 next_elapse
= MIN(converted
, next
->realtime
);
1284 next_elapse
= converted
;
1287 next_elapse
= next
->realtime
;
1292 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1293 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1294 _cleanup_strv_free_
char **machines
= NULL
;
1295 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1296 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1297 struct timer_info
*t
;
1305 r
= acquire_bus(BUS_MANAGER
, &bus
);
1309 pager_open(arg_no_pager
, false);
1311 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1315 dual_timestamp_get(&nw
);
1317 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1318 _cleanup_strv_free_
char **triggered
= NULL
;
1319 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1322 if (!endswith(u
->id
, ".timer"))
1325 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1329 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1333 get_last_trigger(bus
, u
->unit_path
, &last
);
1335 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1340 m
= calc_next_elapse(&nw
, &next
);
1342 timer_infos
[c
++] = (struct timer_info
) {
1343 .machine
= u
->machine
,
1346 .last_trigger
= last
,
1347 .triggered
= triggered
,
1350 triggered
= NULL
; /* avoid cleanup */
1353 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1354 (__compar_fn_t
) timer_info_compare
);
1356 output_timers_list(timer_infos
, c
);
1359 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1360 strv_free(t
->triggered
);
1365 static int compare_unit_file_list(const void *a
, const void *b
) {
1366 const char *d1
, *d2
;
1367 const UnitFileList
*u
= a
, *v
= b
;
1369 d1
= strrchr(u
->path
, '.');
1370 d2
= strrchr(v
->path
, '.');
1375 r
= strcasecmp(d1
, d2
);
1380 return strcasecmp(basename(u
->path
), basename(v
->path
));
1383 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1386 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1389 if (!strv_isempty(arg_types
)) {
1392 dot
= strrchr(u
->path
, '.');
1396 if (!strv_find(arg_types
, dot
+1))
1400 if (!strv_isempty(states
) &&
1401 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1407 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1408 unsigned max_id_len
, id_cols
, state_cols
;
1409 const UnitFileList
*u
;
1411 max_id_len
= strlen("UNIT FILE");
1412 state_cols
= strlen("STATE");
1414 for (u
= units
; u
< units
+ c
; u
++) {
1415 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1416 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1420 unsigned basic_cols
;
1422 id_cols
= MIN(max_id_len
, 25u);
1423 basic_cols
= 1 + id_cols
+ state_cols
;
1424 if (basic_cols
< (unsigned) columns())
1425 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1427 id_cols
= max_id_len
;
1429 if (!arg_no_legend
&& c
> 0)
1430 printf("%s%-*s %-*s%s\n",
1432 id_cols
, "UNIT FILE",
1433 state_cols
, "STATE",
1436 for (u
= units
; u
< units
+ c
; u
++) {
1437 _cleanup_free_
char *e
= NULL
;
1438 const char *on
, *off
, *on_underline
= "", *off_underline
= "";
1440 bool underline
= false;
1442 if (u
+ 1 < units
+ c
&&
1443 !streq(unit_type_suffix(u
->path
), unit_type_suffix((u
+ 1)->path
))) {
1444 on_underline
= ansi_underline();
1445 off_underline
= ansi_normal();
1449 if (IN_SET(u
->state
,
1451 UNIT_FILE_MASKED_RUNTIME
,
1454 on
= underline
? ansi_highlight_red_underline() : ansi_highlight_red();
1455 else if (u
->state
== UNIT_FILE_ENABLED
)
1456 on
= underline
? ansi_highlight_green_underline() : ansi_highlight_green();
1459 off
= off_underline
;
1461 id
= basename(u
->path
);
1463 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1465 printf("%s%-*s %s%-*s%s%s\n",
1467 id_cols
, e
? e
: id
,
1468 on
, state_cols
, unit_file_state_to_string(u
->state
), off
,
1473 printf("\n%u unit files listed.\n", c
);
1476 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1477 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1478 _cleanup_free_ UnitFileList
*units
= NULL
;
1485 bool fallback
= false;
1487 if (install_client_side()) {
1493 h
= hashmap_new(&string_hash_ops
);
1497 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1499 unit_file_list_free(h
);
1500 return log_error_errno(r
, "Failed to get unit file list: %m");
1503 n_units
= hashmap_size(h
);
1505 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1507 unit_file_list_free(h
);
1511 HASHMAP_FOREACH(u
, h
, i
) {
1512 if (!output_show_unit_file(u
, NULL
, NULL
))
1519 assert(c
<= n_units
);
1524 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1525 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1528 r
= acquire_bus(BUS_MANAGER
, &bus
);
1532 r
= sd_bus_message_new_method_call(
1535 "org.freedesktop.systemd1",
1536 "/org/freedesktop/systemd1",
1537 "org.freedesktop.systemd1.Manager",
1538 "ListUnitFilesByPatterns");
1540 return bus_log_create_error(r
);
1542 r
= sd_bus_message_append_strv(m
, arg_states
);
1544 return bus_log_create_error(r
);
1546 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1548 return bus_log_create_error(r
);
1550 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1551 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1552 /* Fallback to legacy ListUnitFiles method */
1554 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1555 m
= sd_bus_message_unref(m
);
1556 sd_bus_error_free(&error
);
1558 r
= sd_bus_message_new_method_call(
1561 "org.freedesktop.systemd1",
1562 "/org/freedesktop/systemd1",
1563 "org.freedesktop.systemd1.Manager",
1566 return bus_log_create_error(r
);
1568 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1571 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1573 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1575 return bus_log_parse_error(r
);
1577 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1579 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1582 units
[c
] = (struct UnitFileList
) {
1584 unit_file_state_from_string(state
)
1587 if (output_show_unit_file(&units
[c
],
1588 fallback
? arg_states
: NULL
,
1589 fallback
? strv_skip(argv
, 1) : NULL
))
1594 return bus_log_parse_error(r
);
1596 r
= sd_bus_message_exit_container(reply
);
1598 return bus_log_parse_error(r
);
1601 pager_open(arg_no_pager
, false);
1603 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1604 output_unit_file_list(units
, c
);
1606 if (install_client_side())
1607 for (unit
= units
; unit
< units
+ c
; unit
++)
1613 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1614 _cleanup_free_
char *n
= NULL
;
1615 size_t max_len
= MAX(columns(),20u);
1621 for (i
= level
- 1; i
>= 0; i
--) {
1623 if (len
> max_len
- 3 && !arg_full
) {
1624 printf("%s...\n",max_len
% 2 ? "" : " ");
1627 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1631 if (len
> max_len
- 3 && !arg_full
) {
1632 printf("%s...\n",max_len
% 2 ? "" : " ");
1636 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1640 printf("%s\n", name
);
1644 n
= ellipsize(name
, max_len
-len
, 100);
1652 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1654 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1655 [DEPENDENCY_FORWARD
] = "Requires\0"
1660 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1665 [DEPENDENCY_AFTER
] = "After\0",
1666 [DEPENDENCY_BEFORE
] = "Before\0",
1669 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1670 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1671 _cleanup_strv_free_
char **ret
= NULL
;
1672 _cleanup_free_
char *path
= NULL
;
1678 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1680 path
= unit_dbus_path_from_name(name
);
1684 r
= sd_bus_call_method(
1686 "org.freedesktop.systemd1",
1688 "org.freedesktop.DBus.Properties",
1692 "s", "org.freedesktop.systemd1.Unit");
1694 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1696 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1698 return bus_log_parse_error(r
);
1700 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1703 r
= sd_bus_message_read(reply
, "s", &prop
);
1705 return bus_log_parse_error(r
);
1707 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1708 r
= sd_bus_message_skip(reply
, "v");
1710 return bus_log_parse_error(r
);
1713 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1715 return bus_log_parse_error(r
);
1717 r
= bus_message_read_strv_extend(reply
, &ret
);
1719 return bus_log_parse_error(r
);
1721 r
= sd_bus_message_exit_container(reply
);
1723 return bus_log_parse_error(r
);
1726 r
= sd_bus_message_exit_container(reply
);
1728 return bus_log_parse_error(r
);
1732 return bus_log_parse_error(r
);
1734 r
= sd_bus_message_exit_container(reply
);
1736 return bus_log_parse_error(r
);
1738 *deps
= strv_uniq(ret
);
1744 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1745 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1747 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1749 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1752 return strcasecmp(*a
, *b
);
1755 static int list_dependencies_one(
1760 unsigned int branches
) {
1762 _cleanup_strv_free_
char **deps
= NULL
;
1770 r
= strv_extend(units
, name
);
1774 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1778 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1780 STRV_FOREACH(c
, deps
) {
1781 if (strv_contains(*units
, *c
)) {
1783 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1793 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1796 (void) get_state_one_unit(bus
, *c
, &active_state
);
1798 switch (active_state
) {
1800 case UNIT_RELOADING
:
1801 case UNIT_ACTIVATING
:
1802 on
= ansi_highlight_green();
1806 case UNIT_DEACTIVATING
:
1811 on
= ansi_highlight_red();
1815 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1818 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1822 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1823 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1830 strv_remove(*units
, name
);
1835 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1836 _cleanup_strv_free_
char **units
= NULL
;
1837 _cleanup_free_
char *unit
= NULL
;
1843 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1845 return log_error_errno(r
, "Failed to mangle unit name: %m");
1849 u
= SPECIAL_DEFAULT_TARGET
;
1851 r
= acquire_bus(BUS_MANAGER
, &bus
);
1855 pager_open(arg_no_pager
, false);
1859 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1862 struct machine_info
{
1866 char *control_group
;
1867 uint32_t n_failed_units
;
1872 static const struct bus_properties_map machine_info_property_map
[] = {
1873 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1874 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1875 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1876 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1877 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1881 static void machine_info_clear(struct machine_info
*info
) {
1886 free(info
->control_group
);
1890 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1896 for (i
= 0; i
< n
; i
++)
1897 machine_info_clear(&machine_infos
[i
]);
1899 free(machine_infos
);
1902 static int compare_machine_info(const void *a
, const void *b
) {
1903 const struct machine_info
*u
= a
, *v
= b
;
1905 if (u
->is_host
!= v
->is_host
)
1906 return u
->is_host
> v
->is_host
? -1 : 1;
1908 return strcasecmp(u
->name
, v
->name
);
1911 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1912 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1918 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1925 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, NULL
, mi
);
1932 static bool output_show_machine(const char *name
, char **patterns
) {
1933 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1936 static int get_machine_list(
1938 struct machine_info
**_machine_infos
,
1941 struct machine_info
*machine_infos
= NULL
;
1942 _cleanup_strv_free_
char **m
= NULL
;
1943 _cleanup_free_
char *hn
= NULL
;
1948 hn
= gethostname_malloc();
1952 if (output_show_machine(hn
, patterns
)) {
1953 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1956 machine_infos
[c
].is_host
= true;
1957 machine_infos
[c
].name
= hn
;
1960 (void) get_machine_properties(bus
, &machine_infos
[c
]);
1964 r
= sd_get_machine_names(&m
);
1966 return log_error_errno(r
, "Failed to get machine list: %m");
1968 STRV_FOREACH(i
, m
) {
1969 _cleanup_free_
char *class = NULL
;
1971 if (!output_show_machine(*i
, patterns
))
1974 sd_machine_get_class(*i
, &class);
1975 if (!streq_ptr(class, "container"))
1978 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1979 free_machines_list(machine_infos
, c
);
1983 machine_infos
[c
].is_host
= false;
1984 machine_infos
[c
].name
= strdup(*i
);
1985 if (!machine_infos
[c
].name
) {
1986 free_machines_list(machine_infos
, c
);
1990 (void) get_machine_properties(NULL
, &machine_infos
[c
]);
1994 *_machine_infos
= machine_infos
;
1998 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1999 struct machine_info
*m
;
2002 namelen
= sizeof("NAME") - 1,
2003 statelen
= sizeof("STATE") - 1,
2004 failedlen
= sizeof("FAILED") - 1,
2005 jobslen
= sizeof("JOBS") - 1;
2007 assert(machine_infos
|| n
== 0);
2009 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2010 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
2011 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
2012 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
2013 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
2015 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
2019 if (!arg_no_legend
) {
2023 printf("%-*s %-*s %-*s %-*s\n",
2026 failedlen
, "FAILED",
2030 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
2031 const char *on_state
= "", *off_state
= "";
2032 const char *on_failed
= "", *off_failed
= "";
2033 bool circle
= false;
2035 if (streq_ptr(m
->state
, "degraded")) {
2036 on_state
= ansi_highlight_red();
2037 off_state
= ansi_normal();
2039 } else if (!streq_ptr(m
->state
, "running")) {
2040 on_state
= ansi_highlight_yellow();
2041 off_state
= ansi_normal();
2045 if (m
->n_failed_units
> 0) {
2046 on_failed
= ansi_highlight_red();
2047 off_failed
= ansi_normal();
2049 on_failed
= off_failed
= "";
2052 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
2055 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2056 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
2057 on_state
, statelen
, strna(m
->state
), off_state
,
2058 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2059 jobslen
, m
->n_jobs
);
2061 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2062 namelen
, strna(m
->name
),
2063 on_state
, statelen
, strna(m
->state
), off_state
,
2064 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2065 jobslen
, m
->n_jobs
);
2069 printf("\n%u machines listed.\n", n
);
2072 static int list_machines(int argc
, char *argv
[], void *userdata
) {
2073 struct machine_info
*machine_infos
= NULL
;
2077 if (geteuid() != 0) {
2078 log_error("Must be root.");
2082 r
= acquire_bus(BUS_MANAGER
, &bus
);
2086 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2090 pager_open(arg_no_pager
, false);
2092 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2093 output_machines_list(machine_infos
, r
);
2094 free_machines_list(machine_infos
, r
);
2099 static int get_default(int argc
, char *argv
[], void *userdata
) {
2100 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2101 _cleanup_free_
char *_path
= NULL
;
2105 if (install_client_side()) {
2106 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2108 return log_error_errno(r
, "Failed to get default target: %m");
2113 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2116 r
= acquire_bus(BUS_MANAGER
, &bus
);
2120 r
= sd_bus_call_method(
2122 "org.freedesktop.systemd1",
2123 "/org/freedesktop/systemd1",
2124 "org.freedesktop.systemd1.Manager",
2130 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2132 r
= sd_bus_message_read(reply
, "s", &path
);
2134 return bus_log_parse_error(r
);
2138 printf("%s\n", path
);
2143 static int set_default(int argc
, char *argv
[], void *userdata
) {
2144 _cleanup_free_
char *unit
= NULL
;
2145 UnitFileChange
*changes
= NULL
;
2146 unsigned n_changes
= 0;
2152 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2154 return log_error_errno(r
, "Failed to mangle unit name: %m");
2156 if (install_client_side()) {
2157 r
= unit_file_set_default(arg_scope
, UNIT_FILE_FORCE
, arg_root
, unit
, &changes
, &n_changes
);
2158 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2163 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2164 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2167 polkit_agent_open_if_enabled();
2169 r
= acquire_bus(BUS_MANAGER
, &bus
);
2173 r
= sd_bus_call_method(
2175 "org.freedesktop.systemd1",
2176 "/org/freedesktop/systemd1",
2177 "org.freedesktop.systemd1.Manager",
2183 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2185 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2189 /* Try to reload if enabled */
2191 r
= daemon_reload(argc
, argv
, userdata
);
2197 unit_file_changes_free(changes
, n_changes
);
2202 static int output_waiting_jobs(sd_bus
*bus
, uint32_t id
, const char *method
, const char *prefix
) {
2203 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2204 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2205 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2211 r
= sd_bus_call_method(
2213 "org.freedesktop.systemd1",
2214 "/org/freedesktop/systemd1",
2215 "org.freedesktop.systemd1.Manager",
2221 return log_debug_errno(r
, "Failed to get waiting jobs for job %" PRIu32
, id
);
2223 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2225 return bus_log_parse_error(r
);
2227 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &other_id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0)
2228 printf("%s %u (%s/%s)\n", prefix
, other_id
, name
, type
);
2230 return bus_log_parse_error(r
);
2232 r
= sd_bus_message_exit_container(reply
);
2234 return bus_log_parse_error(r
);
2241 const char *name
, *type
, *state
;
2244 static void output_jobs_list(sd_bus
*bus
, const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2245 unsigned id_len
, unit_len
, type_len
, state_len
;
2246 const struct job_info
*j
;
2247 const char *on
, *off
;
2248 bool shorten
= false;
2250 assert(n
== 0 || jobs
);
2253 if (!arg_no_legend
) {
2254 on
= ansi_highlight_green();
2255 off
= ansi_normal();
2257 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2262 pager_open(arg_no_pager
, false);
2264 id_len
= strlen("JOB");
2265 unit_len
= strlen("UNIT");
2266 type_len
= strlen("TYPE");
2267 state_len
= strlen("STATE");
2269 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2270 uint32_t id
= j
->id
;
2271 assert(j
->name
&& j
->type
&& j
->state
);
2273 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2274 unit_len
= MAX(unit_len
, strlen(j
->name
));
2275 type_len
= MAX(type_len
, strlen(j
->type
));
2276 state_len
= MAX(state_len
, strlen(j
->state
));
2279 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2280 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2285 printf("%*s %-*s %-*s %-*s\n",
2289 state_len
, "STATE");
2291 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2292 _cleanup_free_
char *e
= NULL
;
2294 if (streq(j
->state
, "running")) {
2295 on
= ansi_highlight();
2296 off
= ansi_normal();
2300 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2301 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2303 on
, unit_len
, e
? e
: j
->name
, off
,
2305 on
, state_len
, j
->state
, off
);
2308 output_waiting_jobs(bus
, j
->id
, "GetJobAfter", "\twaiting for job");
2309 if (arg_jobs_before
)
2310 output_waiting_jobs(bus
, j
->id
, "GetJobBefore", "\tblocking job");
2313 if (!arg_no_legend
) {
2314 on
= ansi_highlight();
2315 off
= ansi_normal();
2317 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2321 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2322 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2325 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2326 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2327 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2328 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2329 _cleanup_free_
struct job_info
*jobs
= NULL
;
2335 bool skipped
= false;
2337 r
= acquire_bus(BUS_MANAGER
, &bus
);
2341 r
= sd_bus_call_method(
2343 "org.freedesktop.systemd1",
2344 "/org/freedesktop/systemd1",
2345 "org.freedesktop.systemd1.Manager",
2351 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2353 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2355 return bus_log_parse_error(r
);
2357 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2358 struct job_info job
= { id
, name
, type
, state
};
2360 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2365 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2371 return bus_log_parse_error(r
);
2373 r
= sd_bus_message_exit_container(reply
);
2375 return bus_log_parse_error(r
);
2377 pager_open(arg_no_pager
, false);
2379 output_jobs_list(bus
, jobs
, c
, skipped
);
2383 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2389 return trivial_method(argc
, argv
, userdata
);
2391 r
= acquire_bus(BUS_MANAGER
, &bus
);
2395 polkit_agent_open_if_enabled();
2397 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2398 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2402 q
= safe_atou32(*name
, &id
);
2404 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2406 q
= sd_bus_call_method(
2408 "org.freedesktop.systemd1",
2409 "/org/freedesktop/systemd1",
2410 "org.freedesktop.systemd1.Manager",
2416 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2425 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2426 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2430 /* We ignore all errors here, since this is used to show a
2433 /* We don't use unit_dbus_path_from_name() directly since we
2434 * don't want to load the unit if it isn't loaded. */
2436 r
= sd_bus_call_method(
2438 "org.freedesktop.systemd1",
2439 "/org/freedesktop/systemd1",
2440 "org.freedesktop.systemd1.Manager",
2448 r
= sd_bus_message_read(reply
, "o", &path
);
2452 r
= sd_bus_get_property_trivial(
2454 "org.freedesktop.systemd1",
2456 "org.freedesktop.systemd1.Unit",
2466 static void warn_unit_file_changed(const char *name
) {
2469 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2470 ansi_highlight_red(),
2473 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2476 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2483 STRV_FOREACH(p
, lp
->search_path
) {
2484 _cleanup_free_
char *path
= NULL
, *lpath
= NULL
;
2487 path
= path_join(NULL
, *p
, unit_name
);
2491 r
= chase_symlinks(path
, arg_root
, 0, &lpath
);
2497 return log_error_errno(r
, "Failed to access path '%s': %m", path
);
2507 static int unit_find_paths(
2509 const char *unit_name
,
2511 char **fragment_path
,
2512 char ***dropin_paths
) {
2514 _cleanup_free_
char *path
= NULL
;
2515 _cleanup_strv_free_
char **dropins
= NULL
;
2519 * Finds where the unit is defined on disk. Returns 0 if the unit
2520 * is not found. Returns 1 if it is found, and sets
2521 * - the path to the unit in *path, if it exists on disk,
2522 * - and a strv of existing drop-ins in *dropins,
2523 * if the arg is not NULL and any dropins were found.
2527 assert(fragment_path
);
2530 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2531 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2532 _cleanup_free_
char *unit
= NULL
;
2534 unit
= unit_dbus_path_from_name(unit_name
);
2538 r
= sd_bus_get_property_string(
2540 "org.freedesktop.systemd1",
2542 "org.freedesktop.systemd1.Unit",
2547 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2550 r
= sd_bus_get_property_strv(
2552 "org.freedesktop.systemd1",
2554 "org.freedesktop.systemd1.Unit",
2559 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2562 _cleanup_set_free_ Set
*names
;
2563 _cleanup_free_
char *template = NULL
;
2565 names
= set_new(NULL
);
2569 r
= unit_file_find_path(lp
, unit_name
, &path
);
2574 r
= unit_name_template(unit_name
, &template);
2575 if (r
< 0 && r
!= -EINVAL
)
2576 return log_error_errno(r
, "Failed to determine template name: %m");
2578 r
= unit_file_find_path(lp
, template, &path
);
2585 /* We found the unit file. If we followed symlinks, this name might be
2586 * different then the unit_name with started with. Look for dropins matching
2587 * that "final" name. */
2588 r
= set_put(names
, basename(path
));
2590 /* No unit file, let's look for dropins matching the original name.
2591 * systemd has fairly complicated rules (based on unit type and provenience),
2592 * which units are allowed not to have the main unit file. We err on the
2593 * side of including too many files, and always try to load dropins. */
2594 r
= set_put(names
, unit_name
);
2596 /* The cases where we allow a unit to exist without the main file are
2597 * never valid for templates. Don't try to load dropins in this case. */
2601 return log_error_errno(r
, "Failed to add unit name: %m");
2604 r
= unit_file_find_dropin_conf_paths(arg_root
, lp
->search_path
,
2605 NULL
, names
, &dropins
);
2613 if (!isempty(path
)) {
2614 *fragment_path
= path
;
2619 if (dropin_paths
&& !strv_isempty(dropins
)) {
2620 *dropin_paths
= dropins
;
2625 if (r
== 0 && !arg_force
)
2626 log_error("No files found for %s.", unit_name
);
2631 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2632 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2633 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2634 _cleanup_free_
char *buf
= NULL
;
2635 UnitActiveState state
;
2640 assert(active_state
);
2642 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2644 r
= sd_bus_call_method(
2646 "org.freedesktop.systemd1",
2647 "/org/freedesktop/systemd1",
2648 "org.freedesktop.systemd1.Manager",
2654 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2655 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2657 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2658 * considered inactive. */
2659 state
= UNIT_INACTIVE
;
2662 r
= sd_bus_message_read(reply
, "o", &path
);
2664 return bus_log_parse_error(r
);
2666 r
= sd_bus_get_property_string(
2668 "org.freedesktop.systemd1",
2670 "org.freedesktop.systemd1.Unit",
2675 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2677 state
= unit_active_state_from_string(buf
);
2678 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2679 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2684 *active_state
= state
;
2688 static int check_triggering_units(
2692 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2693 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2694 _cleanup_strv_free_
char **triggered_by
= NULL
;
2695 bool print_warning_label
= true;
2696 UnitActiveState active_state
;
2700 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2702 return log_error_errno(r
, "Failed to mangle unit name: %m");
2704 path
= unit_dbus_path_from_name(n
);
2708 r
= sd_bus_get_property_string(
2710 "org.freedesktop.systemd1",
2712 "org.freedesktop.systemd1.Unit",
2717 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2719 if (streq(load_state
, "masked"))
2722 r
= sd_bus_get_property_strv(
2724 "org.freedesktop.systemd1",
2726 "org.freedesktop.systemd1.Unit",
2731 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2733 STRV_FOREACH(i
, triggered_by
) {
2734 r
= get_state_one_unit(bus
, *i
, &active_state
);
2738 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2741 if (print_warning_label
) {
2742 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2743 print_warning_label
= false;
2746 log_warning(" %s", *i
);
2752 static const struct {
2755 } unit_actions
[] = {
2756 { "start", "StartUnit" },
2757 { "stop", "StopUnit" },
2758 { "condstop", "StopUnit" },
2759 { "reload", "ReloadUnit" },
2760 { "restart", "RestartUnit" },
2761 { "try-restart", "TryRestartUnit" },
2762 { "condrestart", "TryRestartUnit" },
2763 { "reload-or-restart", "ReloadOrRestartUnit" },
2764 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2765 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2766 { "condreload", "ReloadOrTryRestartUnit" },
2767 { "force-reload", "ReloadOrTryRestartUnit" }
2770 static const char *verb_to_method(const char *verb
) {
2773 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2774 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2775 return unit_actions
[i
].method
;
2780 static const char *method_to_verb(const char *method
) {
2783 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2784 if (streq_ptr(unit_actions
[i
].method
, method
))
2785 return unit_actions
[i
].verb
;
2797 static void wait_context_free(WaitContext
*c
) {
2798 c
->match
= sd_bus_slot_unref(c
->match
);
2799 c
->event
= sd_event_unref(c
->event
);
2800 c
->unit_paths
= set_free_free(c
->unit_paths
);
2803 static int on_properties_changed(sd_bus_message
*m
, void *userdata
, sd_bus_error
*error
) {
2804 WaitContext
*c
= userdata
;
2808 path
= sd_bus_message_get_path(m
);
2809 if (!set_contains(c
->unit_paths
, path
))
2812 /* Check if ActiveState changed to inactive/failed */
2813 /* (s interface, a{sv} changed_properties, as invalidated_properties) */
2814 r
= sd_bus_message_skip(m
, "s");
2816 return bus_log_parse_error(r
);
2818 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "{sv}");
2820 return bus_log_parse_error(r
);
2822 while ((r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
2825 r
= sd_bus_message_read(m
, "s", &s
);
2827 return bus_log_parse_error(r
);
2829 if (streq(s
, "ActiveState")) {
2832 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_VARIANT
, "s");
2834 return bus_log_parse_error(r
);
2836 r
= sd_bus_message_read(m
, "s", &s
);
2838 return bus_log_parse_error(r
);
2840 is_failed
= streq(s
, "failed");
2841 if (streq(s
, "inactive") || is_failed
) {
2842 log_debug("%s became %s, dropping from --wait tracking", path
, s
);
2843 free(set_remove(c
->unit_paths
, path
));
2844 c
->any_failed
= c
->any_failed
|| is_failed
;
2846 log_debug("ActiveState on %s changed to %s", path
, s
);
2848 break; /* no need to dissect the rest of the message */
2850 /* other property */
2851 r
= sd_bus_message_skip(m
, "v");
2853 return bus_log_parse_error(r
);
2855 r
= sd_bus_message_exit_container(m
);
2857 return bus_log_parse_error(r
);
2860 return bus_log_parse_error(r
);
2862 if (set_isempty(c
->unit_paths
))
2863 sd_event_exit(c
->event
, EXIT_SUCCESS
);
2868 static int start_unit_one(
2873 sd_bus_error
*error
,
2875 WaitContext
*wait_context
) {
2877 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2887 _cleanup_free_
char *unit_path
= NULL
;
2890 log_debug("Watching for property changes of %s", name
);
2891 r
= sd_bus_call_method(
2893 "org.freedesktop.systemd1",
2894 "/org/freedesktop/systemd1",
2895 "org.freedesktop.systemd1.Manager",
2901 return log_error_errno(r
, "Failed to RefUnit %s: %s", name
, bus_error_message(error
, r
));
2903 unit_path
= unit_dbus_path_from_name(name
);
2907 r
= set_put_strdup(wait_context
->unit_paths
, unit_path
);
2909 return log_error_errno(r
, "Failed to add unit path %s to set: %m", unit_path
);
2911 mt
= strjoina("type='signal',"
2912 "interface='org.freedesktop.DBus.Properties',"
2913 "path='", unit_path
, "',"
2914 "member='PropertiesChanged'");
2915 r
= sd_bus_add_match(bus
, &wait_context
->match
, mt
, on_properties_changed
, wait_context
);
2917 return log_error_errno(r
, "Failed to add match for PropertiesChanged signal: %m");
2920 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2922 r
= sd_bus_call_method(
2924 "org.freedesktop.systemd1",
2925 "/org/freedesktop/systemd1",
2926 "org.freedesktop.systemd1.Manager",
2934 /* There's always a fallback possible for legacy actions. */
2935 if (arg_action
!= ACTION_SYSTEMCTL
)
2938 verb
= method_to_verb(method
);
2940 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2942 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2943 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2944 log_error("See %s logs and 'systemctl%s status%s %s' for details.",
2945 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2946 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2947 name
[0] == '-' ? " --" : "",
2953 r
= sd_bus_message_read(reply
, "o", &path
);
2955 return bus_log_parse_error(r
);
2957 if (need_daemon_reload(bus
, name
) > 0)
2958 warn_unit_file_changed(name
);
2961 log_debug("Adding %s to the set", path
);
2962 r
= bus_wait_for_jobs_add(w
, path
);
2970 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2971 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2978 STRV_FOREACH(name
, names
) {
2982 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2984 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2986 return log_error_errno(r
, "Failed to mangle name: %m");
2988 if (string_is_glob(t
))
2989 r
= strv_consume(&globs
, t
);
2991 r
= strv_consume(&mangled
, t
);
2996 /* Query the manager only if any of the names are a glob, since
2997 * this is fairly expensive */
2998 if (!strv_isempty(globs
)) {
2999 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3000 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
3001 size_t allocated
, n
;
3003 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
3007 n
= strv_length(mangled
);
3010 for (i
= 0; i
< r
; i
++) {
3011 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
3014 mangled
[n
] = strdup(unit_infos
[i
].id
);
3018 mangled
[++n
] = NULL
;
3023 mangled
= NULL
; /* do not free */
3028 static const struct {
3032 } action_table
[_ACTION_MAX
] = {
3033 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
3034 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
3035 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
3036 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
3037 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3038 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3039 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
3040 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
3041 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
3042 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
3043 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
3044 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
3045 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
3046 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
3047 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
3050 static enum action
verb_to_action(const char *verb
) {
3053 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
3054 if (streq_ptr(action_table
[i
].verb
, verb
))
3057 return _ACTION_INVALID
;
3060 static int start_unit(int argc
, char *argv
[], void *userdata
) {
3061 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
3062 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
3063 _cleanup_strv_free_
char **names
= NULL
;
3065 _cleanup_(wait_context_free
) WaitContext wait_context
= {};
3069 if (arg_wait
&& !strstr(argv
[0], "start")) {
3070 log_error("--wait may only be used with a command that starts units.");
3074 /* we cannot do sender tracking on the private bus, so we need the full
3075 * one for RefUnit to implement --wait */
3076 r
= acquire_bus(arg_wait
? BUS_FULL
: BUS_MANAGER
, &bus
);
3080 ask_password_agent_open_if_enabled();
3081 polkit_agent_open_if_enabled();
3083 if (arg_action
== ACTION_SYSTEMCTL
) {
3086 method
= verb_to_method(argv
[0]);
3087 action
= verb_to_action(argv
[0]);
3089 if (streq(argv
[0], "isolate")) {
3093 mode
= action_table
[action
].mode
?: arg_job_mode
;
3095 one_name
= action_table
[action
].target
;
3097 assert(arg_action
< ELEMENTSOF(action_table
));
3098 assert(action_table
[arg_action
].target
);
3100 method
= "StartUnit";
3102 mode
= action_table
[arg_action
].mode
;
3103 one_name
= action_table
[arg_action
].target
;
3107 names
= strv_new(one_name
, NULL
);
3109 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
3111 return log_error_errno(r
, "Failed to expand names: %m");
3114 if (!arg_no_block
) {
3115 r
= bus_wait_for_jobs_new(bus
, &w
);
3117 return log_error_errno(r
, "Could not watch jobs: %m");
3121 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3123 wait_context
.unit_paths
= set_new(&string_hash_ops
);
3124 if (!wait_context
.unit_paths
)
3127 r
= sd_bus_call_method(
3129 "org.freedesktop.systemd1",
3130 "/org/freedesktop/systemd1",
3131 "org.freedesktop.systemd1.Manager",
3136 return log_error_errno(r
, "Failed to enable subscription: %s", bus_error_message(&error
, r
));
3137 r
= sd_event_default(&wait_context
.event
);
3139 return log_error_errno(r
, "Failed to allocate event loop: %m");
3140 r
= sd_bus_attach_event(bus
, wait_context
.event
, 0);
3142 return log_error_errno(r
, "Failed to attach bus to event loop: %m");
3145 STRV_FOREACH(name
, names
) {
3146 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3149 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
, arg_wait
? &wait_context
: NULL
);
3150 if (r
>= 0 && q
< 0)
3151 r
= translate_bus_error_to_exit_status(q
, &error
);
3154 if (!arg_no_block
) {
3155 int q
, arg_count
= 0;
3156 const char* extra_args
[4] = {};
3158 if (arg_scope
!= UNIT_FILE_SYSTEM
)
3159 extra_args
[arg_count
++] = "--user";
3161 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
3162 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
3163 extra_args
[arg_count
++] = "-H";
3164 extra_args
[arg_count
++] = arg_host
;
3165 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
3166 extra_args
[arg_count
++] = "-M";
3167 extra_args
[arg_count
++] = arg_host
;
3170 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
3174 /* When stopping units, warn if they can still be triggered by
3175 * another active unit (socket, path, timer) */
3176 if (!arg_quiet
&& streq(method
, "StopUnit"))
3177 STRV_FOREACH(name
, names
)
3178 check_triggering_units(bus
, *name
);
3181 if (r
>= 0 && arg_wait
) {
3183 q
= sd_event_loop(wait_context
.event
);
3185 return log_error_errno(q
, "Failed to run event loop: %m");
3186 if (wait_context
.any_failed
)
3193 static int logind_set_wall_message(void) {
3195 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3197 _cleanup_free_
char *m
= NULL
;
3200 r
= acquire_bus(BUS_FULL
, &bus
);
3204 m
= strv_join(arg_wall
, " ");
3208 r
= sd_bus_call_method(
3210 "org.freedesktop.login1",
3211 "/org/freedesktop/login1",
3212 "org.freedesktop.login1.Manager",
3221 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
3227 /* Ask systemd-logind, which might grant access to unprivileged users
3228 * through PolicyKit */
3229 static int logind_reboot(enum action a
) {
3231 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3232 const char *method
, *description
;
3236 r
= acquire_bus(BUS_FULL
, &bus
);
3244 description
= "reboot system";
3247 case ACTION_POWEROFF
:
3248 method
= "PowerOff";
3249 description
= "power off system";
3252 case ACTION_SUSPEND
:
3254 description
= "suspend system";
3257 case ACTION_HIBERNATE
:
3258 method
= "Hibernate";
3259 description
= "hibernate system";
3262 case ACTION_HYBRID_SLEEP
:
3263 method
= "HybridSleep";
3264 description
= "put system into hybrid sleep";
3271 polkit_agent_open_if_enabled();
3272 (void) logind_set_wall_message();
3274 r
= sd_bus_call_method(
3276 "org.freedesktop.login1",
3277 "/org/freedesktop/login1",
3278 "org.freedesktop.login1.Manager",
3282 "b", arg_ask_password
);
3284 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
3292 static int logind_check_inhibitors(enum action a
) {
3294 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3295 _cleanup_strv_free_
char **sessions
= NULL
;
3296 const char *what
, *who
, *why
, *mode
;
3303 if (arg_ignore_inhibitors
|| arg_force
> 0)
3315 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
3318 r
= acquire_bus(BUS_FULL
, &bus
);
3322 r
= sd_bus_call_method(
3324 "org.freedesktop.login1",
3325 "/org/freedesktop/login1",
3326 "org.freedesktop.login1.Manager",
3332 /* If logind is not around, then there are no inhibitors... */
3335 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3337 return bus_log_parse_error(r
);
3339 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3340 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3341 _cleanup_strv_free_
char **sv
= NULL
;
3343 if (!streq(mode
, "block"))
3346 sv
= strv_split(what
, ":");
3350 if ((pid_t
) pid
< 0)
3351 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
3353 if (!strv_contains(sv
,
3358 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3361 get_process_comm(pid
, &comm
);
3362 user
= uid_to_name(uid
);
3364 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3365 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3370 return bus_log_parse_error(r
);
3372 r
= sd_bus_message_exit_container(reply
);
3374 return bus_log_parse_error(r
);
3376 /* Check for current sessions */
3377 sd_get_sessions(&sessions
);
3378 STRV_FOREACH(s
, sessions
) {
3379 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3381 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3384 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3387 if (sd_session_get_type(*s
, &type
) < 0 || !STR_IN_SET(type
, "x11", "tty"))
3390 sd_session_get_tty(*s
, &tty
);
3391 sd_session_get_seat(*s
, &seat
);
3392 sd_session_get_service(*s
, &service
);
3393 user
= uid_to_name(uid
);
3395 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3402 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3403 action_table
[a
].verb
);
3411 static int logind_prepare_firmware_setup(void) {
3413 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3417 r
= acquire_bus(BUS_FULL
, &bus
);
3421 r
= sd_bus_call_method(
3423 "org.freedesktop.login1",
3424 "/org/freedesktop/login1",
3425 "org.freedesktop.login1.Manager",
3426 "SetRebootToFirmwareSetup",
3431 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3435 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3440 static int prepare_firmware_setup(void) {
3443 if (!arg_firmware_setup
)
3446 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3448 r
= efi_set_reboot_to_firmware(true);
3450 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3455 return logind_prepare_firmware_setup();
3458 static int set_exit_code(uint8_t code
) {
3459 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3463 r
= acquire_bus(BUS_MANAGER
, &bus
);
3467 r
= sd_bus_call_method(
3469 "org.freedesktop.systemd1",
3470 "/org/freedesktop/systemd1",
3471 "org.freedesktop.systemd1.Manager",
3477 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3482 static int start_special(int argc
, char *argv
[], void *userdata
) {
3488 a
= verb_to_action(argv
[0]);
3490 r
= logind_check_inhibitors(a
);
3494 if (arg_force
>= 2 && geteuid() != 0) {
3495 log_error("Must be root.");
3499 r
= prepare_firmware_setup();
3503 if (a
== ACTION_REBOOT
&& argc
> 1) {
3504 r
= update_reboot_parameter_and_warn(argv
[1]);
3508 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3511 /* If the exit code is not given on the command line,
3512 * don't reset it to zero: just keep it as it might
3513 * have been set previously. */
3515 r
= safe_atou8(argv
[1], &code
);
3517 return log_error_errno(r
, "Invalid exit code.");
3519 r
= set_exit_code(code
);
3524 if (arg_force
>= 2 &&
3531 if (arg_force
>= 1 &&
3538 return trivial_method(argc
, argv
, userdata
);
3540 /* First try logind, to allow authentication with polkit */
3546 ACTION_HYBRID_SLEEP
)) {
3547 r
= logind_reboot(a
);
3550 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3551 /* requested operation is not supported or already in progress */
3554 /* On all other errors, try low-level operation */
3557 return start_unit(argc
, argv
, userdata
);
3560 static int start_system_special(int argc
, char *argv
[], void *userdata
) {
3561 /* Like start_special above, but raises an error when running in user mode */
3563 if (arg_scope
!= UNIT_FILE_SYSTEM
) {
3564 log_error("Bad action for %s mode.",
3565 arg_scope
== UNIT_FILE_GLOBAL
? "--global" : "--user");
3569 return start_special(argc
, argv
, userdata
);
3572 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3573 _cleanup_strv_free_
char **names
= NULL
;
3574 UnitActiveState active_state
;
3580 r
= acquire_bus(BUS_MANAGER
, &bus
);
3584 r
= expand_names(bus
, args
, NULL
, &names
);
3586 return log_error_errno(r
, "Failed to expand names: %m");
3588 STRV_FOREACH(name
, names
) {
3589 r
= get_state_one_unit(bus
, *name
, &active_state
);
3594 puts(unit_active_state_to_string(active_state
));
3596 for (i
= 0; i
< nb_states
; ++i
)
3597 if (good_states
[i
] == active_state
)
3601 /* use the given return code for the case that we won't find
3602 * any unit which matches the list */
3603 return found
? 0 : code
;
3606 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3607 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3608 /* According to LSB: 3, "program is not running" */
3609 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3612 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3613 const UnitActiveState states
[] = { UNIT_FAILED
};
3614 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3617 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3618 _cleanup_strv_free_
char **names
= NULL
;
3619 char *kill_who
= NULL
, **name
;
3623 r
= acquire_bus(BUS_MANAGER
, &bus
);
3627 polkit_agent_open_if_enabled();
3630 arg_kill_who
= "all";
3632 /* --fail was specified */
3633 if (streq(arg_job_mode
, "fail"))
3634 kill_who
= strjoina(arg_kill_who
, "-fail");
3636 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3638 return log_error_errno(r
, "Failed to expand names: %m");
3640 STRV_FOREACH(name
, names
) {
3641 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3643 q
= sd_bus_call_method(
3645 "org.freedesktop.systemd1",
3646 "/org/freedesktop/systemd1",
3647 "org.freedesktop.systemd1.Manager",
3651 "ssi", *name
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3653 log_error_errno(q
, "Failed to kill unit %s: %s", *name
, bus_error_message(&error
, q
));
3662 typedef struct ExecStatusInfo
{
3670 usec_t start_timestamp
;
3671 usec_t exit_timestamp
;
3676 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3679 static void exec_status_info_free(ExecStatusInfo
*i
) {
3688 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3689 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3692 int32_t code
, status
;
3698 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3700 return bus_log_parse_error(r
);
3704 r
= sd_bus_message_read(m
, "s", &path
);
3706 return bus_log_parse_error(r
);
3708 i
->path
= strdup(path
);
3712 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3714 return bus_log_parse_error(r
);
3716 r
= sd_bus_message_read(m
,
3719 &start_timestamp
, &start_timestamp_monotonic
,
3720 &exit_timestamp
, &exit_timestamp_monotonic
,
3724 return bus_log_parse_error(r
);
3727 i
->start_timestamp
= (usec_t
) start_timestamp
;
3728 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3729 i
->pid
= (pid_t
) pid
;
3733 r
= sd_bus_message_exit_container(m
);
3735 return bus_log_parse_error(r
);
3740 typedef struct UnitCondition
{
3747 LIST_FIELDS(struct UnitCondition
, conditions
);
3750 static void unit_condition_free(UnitCondition
*c
) {
3759 DEFINE_TRIVIAL_CLEANUP_FUNC(UnitCondition
*, unit_condition_free
);
3761 typedef struct UnitStatusInfo
{
3763 const char *load_state
;
3764 const char *active_state
;
3765 const char *sub_state
;
3766 const char *unit_file_state
;
3767 const char *unit_file_preset
;
3769 const char *description
;
3770 const char *following
;
3772 char **documentation
;
3774 const char *fragment_path
;
3775 const char *source_path
;
3776 const char *control_group
;
3778 char **dropin_paths
;
3780 const char *load_error
;
3783 usec_t inactive_exit_timestamp
;
3784 usec_t inactive_exit_timestamp_monotonic
;
3785 usec_t active_enter_timestamp
;
3786 usec_t active_exit_timestamp
;
3787 usec_t inactive_enter_timestamp
;
3789 bool need_daemon_reload
;
3795 const char *status_text
;
3796 const char *pid_file
;
3800 usec_t start_timestamp
;
3801 usec_t exit_timestamp
;
3803 int exit_code
, exit_status
;
3805 usec_t condition_timestamp
;
3806 bool condition_result
;
3807 LIST_HEAD(UnitCondition
, conditions
);
3809 usec_t assert_timestamp
;
3811 bool failed_assert_trigger
;
3812 bool failed_assert_negate
;
3813 const char *failed_assert
;
3814 const char *failed_assert_parameter
;
3817 unsigned n_accepted
;
3818 unsigned n_connections
;
3821 /* Pairs of type, path */
3825 const char *sysfs_path
;
3827 /* Mount, Automount */
3834 uint64_t memory_current
;
3835 uint64_t memory_low
;
3836 uint64_t memory_high
;
3837 uint64_t memory_max
;
3838 uint64_t memory_swap_max
;
3839 uint64_t memory_limit
;
3840 uint64_t cpu_usage_nsec
;
3841 uint64_t tasks_current
;
3844 LIST_HEAD(ExecStatusInfo
, exec
);
3847 static void unit_status_info_free(UnitStatusInfo
*info
) {
3851 strv_free(info
->documentation
);
3852 strv_free(info
->dropin_paths
);
3853 strv_free(info
->listen
);
3855 while ((c
= info
->conditions
)) {
3856 LIST_REMOVE(conditions
, info
->conditions
, c
);
3857 unit_condition_free(c
);
3860 while ((p
= info
->exec
)) {
3861 LIST_REMOVE(exec
, info
->exec
, p
);
3862 exec_status_info_free(p
);
3866 static void print_status_info(
3872 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3874 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3875 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3882 /* This shows pretty information about a unit. See
3883 * print_property() for a low-level property printer */
3885 if (streq_ptr(i
->active_state
, "failed")) {
3886 active_on
= ansi_highlight_red();
3887 active_off
= ansi_normal();
3888 } else if (STRPTR_IN_SET(i
->active_state
, "active", "reloading")) {
3889 active_on
= ansi_highlight_green();
3890 active_off
= ansi_normal();
3892 active_on
= active_off
= "";
3894 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3896 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3897 printf(" - %s", i
->description
);
3902 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3904 if (streq_ptr(i
->load_state
, "error")) {
3905 on
= ansi_highlight_red();
3906 off
= ansi_normal();
3910 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3912 if (i
->load_error
!= 0)
3913 printf(" Loaded: %s%s%s (Reason: %s)\n",
3914 on
, strna(i
->load_state
), off
, i
->load_error
);
3915 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3916 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3917 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3918 else if (path
&& !isempty(i
->unit_file_state
))
3919 printf(" Loaded: %s%s%s (%s; %s)\n",
3920 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3922 printf(" Loaded: %s%s%s (%s)\n",
3923 on
, strna(i
->load_state
), off
, path
);
3925 printf(" Loaded: %s%s%s\n",
3926 on
, strna(i
->load_state
), off
);
3929 printf("Transient: yes\n");
3931 if (!strv_isempty(i
->dropin_paths
)) {
3932 _cleanup_free_
char *dir
= NULL
;
3936 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3937 if (! dir
|| last
) {
3938 printf(dir
? " " : " Drop-In: ");
3942 dir
= dirname_malloc(*dropin
);
3948 printf("%s\n %s", dir
,
3949 special_glyph(TREE_RIGHT
));
3952 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3954 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3958 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3960 printf(" Active: %s%s (%s)%s",
3961 active_on
, strna(i
->active_state
), ss
, active_off
);
3963 printf(" Active: %s%s%s",
3964 active_on
, strna(i
->active_state
), active_off
);
3966 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3967 printf(" (Result: %s)", i
->result
);
3969 timestamp
= STRPTR_IN_SET(i
->active_state
, "active", "reloading") ? i
->active_enter_timestamp
:
3970 STRPTR_IN_SET(i
->active_state
, "inactive", "failed") ? i
->inactive_enter_timestamp
:
3971 STRPTR_IN_SET(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3972 i
->active_exit_timestamp
;
3974 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3975 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3978 printf(" since %s; %s\n", s2
, s1
);
3980 printf(" since %s\n", s2
);
3984 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3988 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3989 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3991 printf("Condition: start %scondition failed%s at %s%s%s\n",
3992 ansi_highlight_yellow(), ansi_normal(),
3993 s2
, s1
? "; " : "", strempty(s1
));
3995 LIST_FOREACH(conditions
, c
, i
->conditions
)
3996 if (c
->tristate
< 0)
3999 LIST_FOREACH(conditions
, c
, i
->conditions
)
4000 if (c
->tristate
< 0)
4001 printf(" %s %s=%s%s%s was not met\n",
4002 --n
? special_glyph(TREE_BRANCH
) : special_glyph(TREE_RIGHT
),
4004 c
->trigger
? "|" : "",
4005 c
->negate
? "!" : "",
4009 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
4010 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
4011 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
4013 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
4014 ansi_highlight_red(), ansi_normal(),
4015 s2
, s1
? "; " : "", strempty(s1
));
4016 if (i
->failed_assert_trigger
)
4017 printf(" none of the trigger assertions were met\n");
4018 else if (i
->failed_assert
)
4019 printf(" %s=%s%s was not met\n",
4021 i
->failed_assert_negate
? "!" : "",
4022 i
->failed_assert_parameter
);
4026 printf(" Device: %s\n", i
->sysfs_path
);
4028 printf(" Where: %s\n", i
->where
);
4030 printf(" What: %s\n", i
->what
);
4032 STRV_FOREACH(t
, i
->documentation
)
4033 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
4035 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
4036 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
4039 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
4041 LIST_FOREACH(exec
, p
, i
->exec
) {
4042 _cleanup_free_
char *argv
= NULL
;
4045 /* Only show exited processes here */
4049 argv
= strv_join(p
->argv
, " ");
4050 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
4052 good
= is_clean_exit(p
->code
, p
->status
, EXIT_CLEAN_DAEMON
, NULL
);
4054 on
= ansi_highlight_red();
4055 off
= ansi_normal();
4059 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
4061 if (p
->code
== CLD_EXITED
) {
4064 printf("status=%i", p
->status
);
4066 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
4071 printf("signal=%s", signal_to_string(p
->status
));
4073 printf(")%s\n", off
);
4075 if (i
->main_pid
== p
->pid
&&
4076 i
->start_timestamp
== p
->start_timestamp
&&
4077 i
->exit_timestamp
== p
->start_timestamp
)
4078 /* Let's not show this twice */
4081 if (p
->pid
== i
->control_pid
)
4085 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
4086 if (i
->main_pid
> 0) {
4087 printf(" Main PID: "PID_FMT
, i
->main_pid
);
4090 _cleanup_free_
char *comm
= NULL
;
4091 (void) get_process_comm(i
->main_pid
, &comm
);
4093 printf(" (%s)", comm
);
4094 } else if (i
->exit_code
> 0) {
4095 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
4097 if (i
->exit_code
== CLD_EXITED
) {
4100 printf("status=%i", i
->exit_status
);
4102 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
4107 printf("signal=%s", signal_to_string(i
->exit_status
));
4112 if (i
->control_pid
> 0) {
4113 _cleanup_free_
char *c
= NULL
;
4115 if (i
->main_pid
> 0)
4116 fputs("; Control PID: ", stdout
);
4118 fputs("Cntrl PID: ", stdout
); /* if first in column, abbreviated so it fits alignment */
4120 printf(PID_FMT
, i
->control_pid
);
4122 (void) get_process_comm(i
->control_pid
, &c
);
4131 printf(" Status: \"%s\"\n", i
->status_text
);
4132 if (i
->status_errno
> 0)
4133 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
4135 if (i
->tasks_current
!= (uint64_t) -1) {
4136 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
4138 if (i
->tasks_max
!= (uint64_t) -1)
4139 printf(" (limit: %" PRIu64
")\n", i
->tasks_max
);
4144 if (i
->memory_current
!= (uint64_t) -1) {
4145 char buf
[FORMAT_BYTES_MAX
];
4147 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
4149 if (i
->memory_low
> 0 || i
->memory_high
!= CGROUP_LIMIT_MAX
||
4150 i
->memory_max
!= CGROUP_LIMIT_MAX
|| i
->memory_swap_max
!= CGROUP_LIMIT_MAX
||
4151 i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4152 const char *prefix
= "";
4155 if (i
->memory_low
> 0) {
4156 printf("%slow: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_low
));
4159 if (i
->memory_high
!= CGROUP_LIMIT_MAX
) {
4160 printf("%shigh: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_high
));
4163 if (i
->memory_max
!= CGROUP_LIMIT_MAX
) {
4164 printf("%smax: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_max
));
4167 if (i
->memory_swap_max
!= CGROUP_LIMIT_MAX
) {
4168 printf("%sswap max: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_swap_max
));
4171 if (i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
4172 printf("%slimit: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
4180 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
4181 char buf
[FORMAT_TIMESPAN_MAX
];
4182 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
4185 if (i
->control_group
) {
4186 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4187 static const char prefix
[] = " ";
4190 printf(" CGroup: %s\n", i
->control_group
);
4193 if (c
> sizeof(prefix
) - 1)
4194 c
-= sizeof(prefix
) - 1;
4198 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
4203 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
4205 if (i
->main_pid
> 0)
4206 extra
[k
++] = i
->main_pid
;
4208 if (i
->control_pid
> 0)
4209 extra
[k
++] = i
->control_pid
;
4211 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
4213 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
4216 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
4217 show_journal_by_unit(
4222 i
->inactive_exit_timestamp_monotonic
,
4225 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
4226 SD_JOURNAL_LOCAL_ONLY
,
4227 arg_scope
== UNIT_FILE_SYSTEM
,
4230 if (i
->need_daemon_reload
)
4231 warn_unit_file_changed(i
->id
);
4234 static void show_unit_help(UnitStatusInfo
*i
) {
4239 if (!i
->documentation
) {
4240 log_info("Documentation for %s not known.", i
->id
);
4244 STRV_FOREACH(p
, i
->documentation
)
4245 if (startswith(*p
, "man:"))
4246 show_man_page(*p
+ 4, false);
4248 log_info("Can't show: %s", *p
);
4251 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
4258 switch (contents
[0]) {
4260 case SD_BUS_TYPE_STRING
: {
4263 r
= sd_bus_message_read(m
, "s", &s
);
4265 return bus_log_parse_error(r
);
4268 if (streq(name
, "Id"))
4270 else if (streq(name
, "LoadState"))
4272 else if (streq(name
, "ActiveState"))
4273 i
->active_state
= s
;
4274 else if (streq(name
, "SubState"))
4276 else if (streq(name
, "Description"))
4278 else if (streq(name
, "FragmentPath"))
4279 i
->fragment_path
= s
;
4280 else if (streq(name
, "SourcePath"))
4283 else if (streq(name
, "DefaultControlGroup")) {
4285 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
4287 i
->control_group
= e
;
4290 else if (streq(name
, "ControlGroup"))
4291 i
->control_group
= s
;
4292 else if (streq(name
, "StatusText"))
4294 else if (streq(name
, "PIDFile"))
4296 else if (streq(name
, "SysFSPath"))
4298 else if (streq(name
, "Where"))
4300 else if (streq(name
, "What"))
4302 else if (streq(name
, "Following"))
4304 else if (streq(name
, "UnitFileState"))
4305 i
->unit_file_state
= s
;
4306 else if (streq(name
, "UnitFilePreset"))
4307 i
->unit_file_preset
= s
;
4308 else if (streq(name
, "Result"))
4315 case SD_BUS_TYPE_BOOLEAN
: {
4318 r
= sd_bus_message_read(m
, "b", &b
);
4320 return bus_log_parse_error(r
);
4322 if (streq(name
, "Accept"))
4324 else if (streq(name
, "NeedDaemonReload"))
4325 i
->need_daemon_reload
= b
;
4326 else if (streq(name
, "ConditionResult"))
4327 i
->condition_result
= b
;
4328 else if (streq(name
, "AssertResult"))
4329 i
->assert_result
= b
;
4330 else if (streq(name
, "Transient"))
4336 case SD_BUS_TYPE_UINT32
: {
4339 r
= sd_bus_message_read(m
, "u", &u
);
4341 return bus_log_parse_error(r
);
4343 if (streq(name
, "MainPID")) {
4345 i
->main_pid
= (pid_t
) u
;
4348 } else if (streq(name
, "ControlPID"))
4349 i
->control_pid
= (pid_t
) u
;
4350 else if (streq(name
, "ExecMainPID")) {
4352 i
->main_pid
= (pid_t
) u
;
4353 } else if (streq(name
, "NAccepted"))
4355 else if (streq(name
, "NConnections"))
4356 i
->n_connections
= u
;
4361 case SD_BUS_TYPE_INT32
: {
4364 r
= sd_bus_message_read(m
, "i", &j
);
4366 return bus_log_parse_error(r
);
4368 if (streq(name
, "ExecMainCode"))
4369 i
->exit_code
= (int) j
;
4370 else if (streq(name
, "ExecMainStatus"))
4371 i
->exit_status
= (int) j
;
4372 else if (streq(name
, "StatusErrno"))
4373 i
->status_errno
= (int) j
;
4378 case SD_BUS_TYPE_UINT64
: {
4381 r
= sd_bus_message_read(m
, "t", &u
);
4383 return bus_log_parse_error(r
);
4385 if (streq(name
, "ExecMainStartTimestamp"))
4386 i
->start_timestamp
= (usec_t
) u
;
4387 else if (streq(name
, "ExecMainExitTimestamp"))
4388 i
->exit_timestamp
= (usec_t
) u
;
4389 else if (streq(name
, "ActiveEnterTimestamp"))
4390 i
->active_enter_timestamp
= (usec_t
) u
;
4391 else if (streq(name
, "InactiveEnterTimestamp"))
4392 i
->inactive_enter_timestamp
= (usec_t
) u
;
4393 else if (streq(name
, "InactiveExitTimestamp"))
4394 i
->inactive_exit_timestamp
= (usec_t
) u
;
4395 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4396 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4397 else if (streq(name
, "ActiveExitTimestamp"))
4398 i
->active_exit_timestamp
= (usec_t
) u
;
4399 else if (streq(name
, "ConditionTimestamp"))
4400 i
->condition_timestamp
= (usec_t
) u
;
4401 else if (streq(name
, "AssertTimestamp"))
4402 i
->assert_timestamp
= (usec_t
) u
;
4403 else if (streq(name
, "MemoryCurrent"))
4404 i
->memory_current
= u
;
4405 else if (streq(name
, "MemoryLow"))
4407 else if (streq(name
, "MemoryHigh"))
4409 else if (streq(name
, "MemoryMax"))
4411 else if (streq(name
, "MemorySwapMax"))
4412 i
->memory_swap_max
= u
;
4413 else if (streq(name
, "MemoryLimit"))
4414 i
->memory_limit
= u
;
4415 else if (streq(name
, "TasksCurrent"))
4416 i
->tasks_current
= u
;
4417 else if (streq(name
, "TasksMax"))
4419 else if (streq(name
, "CPUUsageNSec"))
4420 i
->cpu_usage_nsec
= u
;
4425 case SD_BUS_TYPE_ARRAY
:
4427 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4428 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4430 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4432 return bus_log_parse_error(r
);
4434 info
= new0(ExecStatusInfo
, 1);
4438 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4440 info
->name
= strdup(name
);
4444 LIST_PREPEND(exec
, i
->exec
, info
);
4446 info
= new0(ExecStatusInfo
, 1);
4452 return bus_log_parse_error(r
);
4454 r
= sd_bus_message_exit_container(m
);
4456 return bus_log_parse_error(r
);
4460 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4461 const char *type
, *path
;
4463 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4465 return bus_log_parse_error(r
);
4467 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4469 r
= strv_extend(&i
->listen
, type
);
4473 r
= strv_extend(&i
->listen
, path
);
4478 return bus_log_parse_error(r
);
4480 r
= sd_bus_message_exit_container(m
);
4482 return bus_log_parse_error(r
);
4486 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4488 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4490 return bus_log_parse_error(r
);
4492 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4494 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4496 return bus_log_parse_error(r
);
4498 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4499 const char *cond
, *param
;
4500 int trigger
, negate
;
4503 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4505 return bus_log_parse_error(r
);
4507 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4508 _cleanup_(unit_condition_freep
) UnitCondition
*c
= NULL
;
4510 log_debug("%s trigger=%d negate=%d %s →%d", cond
, trigger
, negate
, param
, state
);
4512 c
= new0(UnitCondition
, 1);
4516 c
->name
= strdup(cond
);
4517 c
->param
= strdup(param
);
4518 if (!c
->name
|| !c
->param
)
4521 c
->trigger
= trigger
;
4523 c
->tristate
= state
;
4525 LIST_PREPEND(conditions
, i
->conditions
, c
);
4529 return bus_log_parse_error(r
);
4531 r
= sd_bus_message_exit_container(m
);
4533 return bus_log_parse_error(r
);
4535 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4536 const char *cond
, *param
;
4537 int trigger
, negate
;
4540 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4542 return bus_log_parse_error(r
);
4544 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4545 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4546 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4547 i
->failed_assert
= cond
;
4548 i
->failed_assert_trigger
= trigger
;
4549 i
->failed_assert_negate
= negate
;
4550 i
->failed_assert_parameter
= param
;
4554 return bus_log_parse_error(r
);
4556 r
= sd_bus_message_exit_container(m
);
4558 return bus_log_parse_error(r
);
4565 case SD_BUS_TYPE_STRUCT_BEGIN
:
4567 if (streq(name
, "LoadError")) {
4568 const char *n
, *message
;
4570 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4572 return bus_log_parse_error(r
);
4574 if (!isempty(message
))
4575 i
->load_error
= message
;
4588 r
= sd_bus_message_skip(m
, contents
);
4590 return bus_log_parse_error(r
);
4595 #define print_prop(name, fmt, ...) \
4598 printf(fmt "\n", __VA_ARGS__); \
4600 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4603 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4609 /* This is a low-level property printer, see
4610 * print_status_info() for the nicer output */
4612 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4613 /* skip what we didn't read */
4614 r
= sd_bus_message_skip(m
, contents
);
4618 switch (contents
[0]) {
4620 case SD_BUS_TYPE_STRUCT_BEGIN
:
4622 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4625 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4627 return bus_log_parse_error(r
);
4630 print_prop(name
, "%"PRIu32
, u
);
4632 print_prop(name
, "%s", "");
4636 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4639 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4641 return bus_log_parse_error(r
);
4643 if (arg_all
|| !isempty(s
))
4644 print_prop(name
, "%s", s
);
4648 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4649 const char *a
= NULL
, *b
= NULL
;
4651 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4653 return bus_log_parse_error(r
);
4655 if (arg_all
|| !isempty(a
) || !isempty(b
))
4656 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4659 } else if (streq_ptr(name
, "SystemCallFilter")) {
4660 _cleanup_strv_free_
char **l
= NULL
;
4663 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4665 return bus_log_parse_error(r
);
4667 r
= sd_bus_message_read(m
, "b", &whitelist
);
4669 return bus_log_parse_error(r
);
4671 r
= sd_bus_message_read_strv(m
, &l
);
4673 return bus_log_parse_error(r
);
4675 r
= sd_bus_message_exit_container(m
);
4677 return bus_log_parse_error(r
);
4679 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4684 fputs(name
, stdout
);
4691 STRV_FOREACH(i
, l
) {
4699 fputc('\n', stdout
);
4707 case SD_BUS_TYPE_ARRAY
:
4709 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4713 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4715 return bus_log_parse_error(r
);
4717 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4718 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path
, yes_no(ignore
));
4721 return bus_log_parse_error(r
);
4723 r
= sd_bus_message_exit_container(m
);
4725 return bus_log_parse_error(r
);
4729 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4730 const char *type
, *path
;
4732 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4734 return bus_log_parse_error(r
);
4736 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4737 print_prop(type
, "%s", path
);
4739 return bus_log_parse_error(r
);
4741 r
= sd_bus_message_exit_container(m
);
4743 return bus_log_parse_error(r
);
4747 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4748 const char *type
, *path
;
4750 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4752 return bus_log_parse_error(r
);
4754 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4758 printf("Listen%s=%s\n", type
, path
);
4760 return bus_log_parse_error(r
);
4762 r
= sd_bus_message_exit_container(m
);
4764 return bus_log_parse_error(r
);
4768 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4770 uint64_t value
, next_elapse
;
4772 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4774 return bus_log_parse_error(r
);
4776 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4777 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4779 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4780 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4781 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4784 return bus_log_parse_error(r
);
4786 r
= sd_bus_message_exit_container(m
);
4788 return bus_log_parse_error(r
);
4792 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4793 ExecStatusInfo info
= {};
4795 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4797 return bus_log_parse_error(r
);
4799 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4800 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4801 _cleanup_free_
char *tt
;
4803 tt
= strv_join(info
.argv
, " ");
4806 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4809 yes_no(info
.ignore
),
4810 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4811 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4813 sigchld_code_to_string(info
.code
),
4815 info
.code
== CLD_EXITED
? "" : "/",
4816 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4819 strv_free(info
.argv
);
4823 r
= sd_bus_message_exit_container(m
);
4825 return bus_log_parse_error(r
);
4829 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4830 const char *path
, *rwm
;
4832 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4834 return bus_log_parse_error(r
);
4836 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4837 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4839 return bus_log_parse_error(r
);
4841 r
= sd_bus_message_exit_container(m
);
4843 return bus_log_parse_error(r
);
4847 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4848 STR_IN_SET(name
, "IODeviceWeight", "BlockIODeviceWeight")) {
4852 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4854 return bus_log_parse_error(r
);
4856 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4857 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4859 return bus_log_parse_error(r
);
4861 r
= sd_bus_message_exit_container(m
);
4863 return bus_log_parse_error(r
);
4867 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&&
4868 (cgroup_io_limit_type_from_string(name
) >= 0 ||
4869 STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth"))) {
4873 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4875 return bus_log_parse_error(r
);
4877 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4878 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4880 return bus_log_parse_error(r
);
4882 r
= sd_bus_message_exit_container(m
);
4884 return bus_log_parse_error(r
);
4892 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4894 return bus_log_parse_error(r
);
4897 r
= sd_bus_message_skip(m
, contents
);
4899 return bus_log_parse_error(r
);
4902 printf("%s=[unprintable]\n", name
);
4908 static int show_one(
4913 bool show_properties
,
4917 static const struct bus_properties_map property_map
[] = {
4918 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
4919 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
) },
4923 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4924 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4925 _cleanup_set_free_ Set
*found_properties
= NULL
;
4926 _cleanup_(unit_status_info_free
) UnitStatusInfo info
= {
4927 .memory_current
= (uint64_t) -1,
4928 .memory_high
= CGROUP_LIMIT_MAX
,
4929 .memory_max
= CGROUP_LIMIT_MAX
,
4930 .memory_swap_max
= CGROUP_LIMIT_MAX
,
4931 .memory_limit
= (uint64_t) -1,
4932 .cpu_usage_nsec
= (uint64_t) -1,
4933 .tasks_current
= (uint64_t) -1,
4934 .tasks_max
= (uint64_t) -1,
4941 log_debug("Showing one %s", path
);
4943 r
= sd_bus_call_method(
4945 "org.freedesktop.systemd1",
4947 "org.freedesktop.DBus.Properties",
4953 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4956 r
= bus_message_map_all_properties(reply
, property_map
, &error
, &info
);
4958 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
4960 if (streq_ptr(info
.load_state
, "not-found") && streq_ptr(info
.active_state
, "inactive")) {
4961 log_full(streq(verb
, "status") ? LOG_ERR
: LOG_DEBUG
,
4962 "Unit %s could not be found.", unit
);
4964 if (streq(verb
, "status"))
4965 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
;
4967 if (!streq(verb
, "show"))
4971 r
= sd_bus_message_rewind(reply
, true);
4973 return log_error_errno(r
, "Failed to rewind: %s", bus_error_message(&error
, r
));
4976 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4978 return bus_log_parse_error(r
);
4985 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4986 const char *name
, *contents
;
4988 r
= sd_bus_message_read(reply
, "s", &name
);
4990 return bus_log_parse_error(r
);
4992 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4994 return bus_log_parse_error(r
);
4996 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4998 return bus_log_parse_error(r
);
5000 if (show_properties
) {
5001 r
= set_ensure_allocated(&found_properties
, &string_hash_ops
);
5005 r
= set_put(found_properties
, name
);
5006 if (r
< 0 && r
!= EEXIST
)
5009 r
= print_property(name
, reply
, contents
);
5011 r
= status_property(name
, reply
, &info
, contents
);
5015 r
= sd_bus_message_exit_container(reply
);
5017 return bus_log_parse_error(r
);
5019 r
= sd_bus_message_exit_container(reply
);
5021 return bus_log_parse_error(r
);
5024 return bus_log_parse_error(r
);
5026 r
= sd_bus_message_exit_container(reply
);
5028 return bus_log_parse_error(r
);
5031 if (show_properties
) {
5034 STRV_FOREACH(pp
, arg_properties
)
5035 if (!set_contains(found_properties
, *pp
))
5036 log_debug("Property %s does not exist.", *pp
);
5038 } else if (streq(verb
, "help"))
5039 show_unit_help(&info
);
5040 else if (streq(verb
, "status")) {
5041 print_status_info(bus
, &info
, ellipsized
);
5043 if (info
.active_state
&& !STR_IN_SET(info
.active_state
, "active", "reloading"))
5044 r
= EXIT_PROGRAM_NOT_RUNNING
;
5046 r
= EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
;
5052 static int get_unit_dbus_path_by_pid(
5057 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5058 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5062 r
= sd_bus_call_method(
5064 "org.freedesktop.systemd1",
5065 "/org/freedesktop/systemd1",
5066 "org.freedesktop.systemd1.Manager",
5072 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
5074 r
= sd_bus_message_read(reply
, "o", &u
);
5076 return bus_log_parse_error(r
);
5086 static int show_all(
5089 bool show_properties
,
5093 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5094 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
5099 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
5103 pager_open(arg_no_pager
, false);
5107 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
5109 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
5110 _cleanup_free_
char *p
= NULL
;
5112 p
= unit_dbus_path_from_name(u
->id
);
5116 r
= show_one(verb
, bus
, p
, u
->id
, show_properties
, new_line
, ellipsized
);
5119 else if (r
> 0 && ret
== 0)
5126 static int show_system_status(sd_bus
*bus
) {
5127 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
5128 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5129 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
5130 _cleanup_free_
char *hn
= NULL
;
5131 const char *on
, *off
;
5134 hn
= gethostname_malloc();
5138 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &error
, &mi
);
5140 return log_error_errno(r
, "Failed to read server status: %s", bus_error_message(&error
, r
));
5142 if (streq_ptr(mi
.state
, "degraded")) {
5143 on
= ansi_highlight_red();
5144 off
= ansi_normal();
5145 } else if (!streq_ptr(mi
.state
, "running")) {
5146 on
= ansi_highlight_yellow();
5147 off
= ansi_normal();
5151 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
5153 printf(" State: %s%s%s\n",
5154 on
, strna(mi
.state
), off
);
5156 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
5157 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
5159 printf(" Since: %s; %s\n",
5160 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
5161 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
5163 printf(" CGroup: %s\n", mi
.control_group
?: "/");
5164 if (IN_SET(arg_transport
,
5165 BUS_TRANSPORT_LOCAL
,
5166 BUS_TRANSPORT_MACHINE
)) {
5167 static const char prefix
[] = " ";
5171 if (c
> sizeof(prefix
) - 1)
5172 c
-= sizeof(prefix
) - 1;
5176 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
5182 static int show(int argc
, char *argv
[], void *userdata
) {
5183 bool show_properties
, show_status
, show_help
, new_line
= false;
5184 bool ellipsized
= false;
5190 show_properties
= streq(argv
[0], "show");
5191 show_status
= streq(argv
[0], "status");
5192 show_help
= streq(argv
[0], "help");
5194 if (show_help
&& argc
<= 1) {
5195 log_error("This command expects one or more unit names. Did you mean --help?");
5199 r
= acquire_bus(BUS_MANAGER
, &bus
);
5203 pager_open(arg_no_pager
, false);
5206 /* Increase max number of open files to 16K if we can, we
5207 * might needs this when browsing journal files, which might
5208 * be split up into many files. */
5209 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
5211 /* If no argument is specified inspect the manager itself */
5212 if (show_properties
&& argc
<= 1)
5213 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", NULL
, show_properties
, &new_line
, &ellipsized
);
5215 if (show_status
&& argc
<= 1) {
5217 show_system_status(bus
);
5221 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
5223 _cleanup_free_
char **patterns
= NULL
;
5226 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
5227 _cleanup_free_
char *path
= NULL
, *unit
= NULL
;
5230 if (safe_atou32(*name
, &id
) < 0) {
5231 if (strv_push(&patterns
, *name
) < 0)
5235 } else if (show_properties
) {
5236 /* Interpret as job id */
5237 if (asprintf(&path
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
5241 /* Interpret as PID */
5242 r
= get_unit_dbus_path_by_pid(bus
, id
, &path
);
5248 r
= unit_name_from_dbus_path(path
, &unit
);
5253 r
= show_one(argv
[0], bus
, path
, unit
, show_properties
, &new_line
, &ellipsized
);
5256 else if (r
> 0 && ret
== 0)
5260 if (!strv_isempty(patterns
)) {
5261 _cleanup_strv_free_
char **names
= NULL
;
5263 r
= expand_names(bus
, patterns
, NULL
, &names
);
5265 return log_error_errno(r
, "Failed to expand names: %m");
5267 STRV_FOREACH(name
, names
) {
5268 _cleanup_free_
char *path
;
5270 path
= unit_dbus_path_from_name(*name
);
5274 r
= show_one(argv
[0], bus
, path
, *name
, show_properties
, &new_line
, &ellipsized
);
5277 if (r
> 0 && ret
== 0)
5283 if (ellipsized
&& !arg_quiet
)
5284 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
5289 static int cat_file(const char *filename
, bool newline
) {
5290 _cleanup_close_
int fd
;
5292 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
5296 printf("%s%s# %s%s\n",
5297 newline
? "\n" : "",
5298 ansi_highlight_blue(),
5303 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, 0);
5306 static int cat(int argc
, char *argv
[], void *userdata
) {
5307 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5308 _cleanup_strv_free_
char **names
= NULL
;
5314 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5315 log_error("Cannot remotely cat units.");
5319 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
5321 return log_error_errno(r
, "Failed to determine unit paths: %m");
5323 r
= acquire_bus(BUS_MANAGER
, &bus
);
5327 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5329 return log_error_errno(r
, "Failed to expand names: %m");
5331 pager_open(arg_no_pager
, false);
5333 STRV_FOREACH(name
, names
) {
5334 _cleanup_free_
char *fragment_path
= NULL
;
5335 _cleanup_strv_free_
char **dropin_paths
= NULL
;
5338 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
5349 if (need_daemon_reload(bus
, *name
) > 0) /* ignore errors (<0), this is informational output */
5351 "%s# Warning: %s changed on disk, the version systemd has loaded is outdated.\n"
5352 "%s# This output shows the current version of the unit's original fragment and drop-in files.\n"
5353 "%s# If fragments or drop-ins were added or removed, they are not properly reflected in this output.\n"
5354 "%s# Run 'systemctl%s daemon-reload' to reload units.%s\n",
5355 ansi_highlight_red(),
5357 ansi_highlight_red(),
5358 ansi_highlight_red(),
5359 ansi_highlight_red(),
5360 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
5363 if (fragment_path
) {
5364 r
= cat_file(fragment_path
, false);
5366 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
5369 STRV_FOREACH(path
, dropin_paths
) {
5370 r
= cat_file(*path
, path
== dropin_paths
);
5372 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
5379 static int set_property(int argc
, char *argv
[], void *userdata
) {
5380 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5381 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5382 _cleanup_free_
char *n
= NULL
;
5386 r
= acquire_bus(BUS_MANAGER
, &bus
);
5390 polkit_agent_open_if_enabled();
5392 r
= sd_bus_message_new_method_call(
5395 "org.freedesktop.systemd1",
5396 "/org/freedesktop/systemd1",
5397 "org.freedesktop.systemd1.Manager",
5398 "SetUnitProperties");
5400 return bus_log_create_error(r
);
5402 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
5404 return log_error_errno(r
, "Failed to mangle unit name: %m");
5406 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
5408 return bus_log_create_error(r
);
5410 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
5412 return bus_log_create_error(r
);
5414 r
= bus_append_unit_property_assignment_many(m
, strv_skip(argv
, 2));
5418 r
= sd_bus_message_close_container(m
);
5420 return bus_log_create_error(r
);
5422 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5424 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
5429 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5430 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5431 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5436 r
= acquire_bus(BUS_MANAGER
, &bus
);
5440 polkit_agent_open_if_enabled();
5442 switch (arg_action
) {
5449 method
= "Reexecute";
5452 case ACTION_SYSTEMCTL
:
5453 method
= streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5454 /* "daemon-reload" */ "Reload";
5458 assert_not_reached("Unexpected action");
5461 r
= sd_bus_message_new_method_call(
5464 "org.freedesktop.systemd1",
5465 "/org/freedesktop/systemd1",
5466 "org.freedesktop.systemd1.Manager",
5469 return bus_log_create_error(r
);
5471 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5472 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5473 * their timeout, and for everything else there's the same time budget in place. */
5475 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
5477 /* On reexecution, we expect a disconnect, not a reply */
5478 if (IN_SET(r
, -ETIMEDOUT
, -ECONNRESET
) && streq(method
, "Reexecute"))
5481 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5482 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5484 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5485 * old ways of doing things, hence don't log any error in that case here. */
5487 return r
< 0 ? r
: 0;
5490 static int trivial_method(int argc
, char *argv
[], void *userdata
) {
5491 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5496 r
= acquire_bus(BUS_MANAGER
, &bus
);
5500 polkit_agent_open_if_enabled();
5503 streq(argv
[0], "clear-jobs") ||
5504 streq(argv
[0], "cancel") ? "ClearJobs" :
5505 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5506 streq(argv
[0], "halt") ? "Halt" :
5507 streq(argv
[0], "reboot") ? "Reboot" :
5508 streq(argv
[0], "kexec") ? "KExec" :
5509 streq(argv
[0], "exit") ? "Exit" :
5510 /* poweroff */ "PowerOff";
5512 r
= sd_bus_call_method(
5514 "org.freedesktop.systemd1",
5515 "/org/freedesktop/systemd1",
5516 "org.freedesktop.systemd1.Manager",
5521 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5522 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5524 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5525 * old ways of doing things, hence don't log any error in that case here. */
5527 return r
< 0 ? r
: 0;
5530 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5531 _cleanup_strv_free_
char **names
= NULL
;
5537 return trivial_method(argc
, argv
, userdata
);
5539 r
= acquire_bus(BUS_MANAGER
, &bus
);
5543 polkit_agent_open_if_enabled();
5545 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5547 return log_error_errno(r
, "Failed to expand names: %m");
5549 STRV_FOREACH(name
, names
) {
5550 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5552 q
= sd_bus_call_method(
5554 "org.freedesktop.systemd1",
5555 "/org/freedesktop/systemd1",
5556 "org.freedesktop.systemd1.Manager",
5562 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5571 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5572 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5573 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5578 r
= acquire_bus(BUS_MANAGER
, &bus
);
5582 pager_open(arg_no_pager
, false);
5584 r
= sd_bus_get_property(
5586 "org.freedesktop.systemd1",
5587 "/org/freedesktop/systemd1",
5588 "org.freedesktop.systemd1.Manager",
5594 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5596 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5598 return bus_log_parse_error(r
);
5600 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5603 return bus_log_parse_error(r
);
5605 r
= sd_bus_message_exit_container(reply
);
5607 return bus_log_parse_error(r
);
5612 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5613 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5614 _cleanup_free_
char *cmdline_init
= NULL
;
5615 const char *root
, *init
;
5619 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5620 log_error("Cannot switch root remotely.");
5624 if (argc
< 2 || argc
> 3) {
5625 log_error("Wrong number of arguments.");
5634 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5635 "init", &cmdline_init
,
5638 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5640 init
= cmdline_init
;
5643 init
= empty_to_null(init
);
5645 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5647 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5648 root_init_path
= strjoina(root
, "/", init
);
5650 /* If the passed init is actually the same as the
5651 * systemd binary, then let's suppress it. */
5652 if (files_same(root_init_path
, root_systemd_path
) > 0)
5656 /* Instruct PID1 to exclude us from its killing spree applied during
5657 * the transition. Otherwise we would exit with a failure status even
5658 * though the switch to the new root has succeed. */
5659 argv_cmdline
[0] = '@';
5661 r
= acquire_bus(BUS_MANAGER
, &bus
);
5665 /* If we are slow to exit after the root switch, the new systemd instance
5666 * will send us a signal to terminate. Just ignore it and exit normally.
5667 * This way the unit does not end up as failed.
5669 r
= ignore_signals(SIGTERM
, -1);
5671 log_warning_errno(r
, "Failed to change disposition of SIGTERM to ignore: %m");
5673 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5675 r
= sd_bus_call_method(
5677 "org.freedesktop.systemd1",
5678 "/org/freedesktop/systemd1",
5679 "org.freedesktop.systemd1.Manager",
5685 (void) default_signals(SIGTERM
, -1);
5687 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5693 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5694 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5695 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5703 r
= acquire_bus(BUS_MANAGER
, &bus
);
5707 polkit_agent_open_if_enabled();
5709 method
= streq(argv
[0], "set-environment")
5711 : "UnsetEnvironment";
5713 r
= sd_bus_message_new_method_call(
5716 "org.freedesktop.systemd1",
5717 "/org/freedesktop/systemd1",
5718 "org.freedesktop.systemd1.Manager",
5721 return bus_log_create_error(r
);
5723 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5725 return bus_log_create_error(r
);
5727 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5729 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5734 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5735 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5736 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5740 r
= acquire_bus(BUS_MANAGER
, &bus
);
5744 polkit_agent_open_if_enabled();
5746 r
= sd_bus_message_new_method_call(
5749 "org.freedesktop.systemd1",
5750 "/org/freedesktop/systemd1",
5751 "org.freedesktop.systemd1.Manager",
5754 return bus_log_create_error(r
);
5757 r
= sd_bus_message_append_strv(m
, environ
);
5761 r
= sd_bus_message_open_container(m
, 'a', "s");
5763 return bus_log_create_error(r
);
5765 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5767 if (!env_name_is_valid(*a
)) {
5768 log_error("Not a valid environment variable name: %s", *a
);
5772 STRV_FOREACH(b
, environ
) {
5775 eq
= startswith(*b
, *a
);
5776 if (eq
&& *eq
== '=') {
5778 r
= sd_bus_message_append(m
, "s", *b
);
5780 return bus_log_create_error(r
);
5787 r
= sd_bus_message_close_container(m
);
5790 return bus_log_create_error(r
);
5792 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5794 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5799 static int enable_sysv_units(const char *verb
, char **args
) {
5802 #if defined(HAVE_SYSV_COMPAT)
5803 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5806 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5808 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5811 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5814 if (!STR_IN_SET(verb
,
5820 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5827 const char *argv
[] = {
5828 ROOTLIBEXECDIR
"/systemd-sysv-install",
5835 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5836 bool found_native
= false, found_sysv
;
5845 if (!endswith(name
, ".service"))
5848 if (path_is_absolute(name
))
5851 j
= unit_file_exists(arg_scope
, &paths
, name
);
5852 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5853 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5854 found_native
= j
!= 0;
5856 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5857 * prefer the native unit */
5858 if (found_native
&& streq(verb
, "is-enabled"))
5861 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5865 p
[strlen(p
) - strlen(".service")] = 0;
5866 found_sysv
= access(p
, F_OK
) >= 0;
5872 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5874 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5877 if (!isempty(arg_root
))
5878 argv
[c
++] = q
= strappend("--root=", arg_root
);
5881 argv
[c
++] = basename(p
);
5884 l
= strv_join((char**)argv
, " ");
5888 log_info("Executing: %s", l
);
5892 return log_error_errno(errno
, "Failed to fork: %m");
5893 else if (pid
== 0) {
5896 (void) reset_all_signal_handlers();
5897 (void) reset_signal_mask();
5899 execv(argv
[0], (char**) argv
);
5900 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
5901 _exit(EXIT_FAILURE
);
5904 j
= wait_for_terminate(pid
, &status
);
5906 return log_error_errno(j
, "Failed to wait for child: %m");
5908 if (status
.si_code
== CLD_EXITED
) {
5909 if (streq(verb
, "is-enabled")) {
5910 if (status
.si_status
== 0) {
5919 } else if (status
.si_status
!= 0)
5920 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
5922 log_error("Unexpected waitid() result.");
5929 /* Remove this entry, so that we don't try enabling it as native unit */
5932 assert(args
[f
] == name
);
5933 strv_remove(args
, name
);
5940 static int mangle_names(char **original_names
, char ***mangled_names
) {
5941 char **i
, **l
, **name
;
5944 l
= i
= new(char*, strv_length(original_names
) + 1);
5948 STRV_FOREACH(name
, original_names
) {
5950 /* When enabling units qualified path names are OK,
5951 * too, hence allow them explicitly. */
5953 if (is_path(*name
)) {
5960 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5963 return log_error_errno(r
, "Failed to mangle unit name: %m");
5976 static int normalize_names(char **names
, bool warn_if_path
) {
5978 bool was_path
= false;
5980 STRV_FOREACH(u
, names
) {
5986 r
= free_and_strdup(u
, basename(*u
));
5988 return log_error_errno(r
, "Failed to normalize unit file path: %m");
5993 if (warn_if_path
&& was_path
)
5994 log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
5999 static int unit_exists(const char *unit
) {
6000 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6001 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6002 _cleanup_free_
char *path
= NULL
;
6003 static const struct bus_properties_map property_map
[] = {
6004 { "LoadState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, load_state
) },
6005 { "ActiveState", "s", map_string_no_copy
, offsetof(UnitStatusInfo
, active_state
)},
6008 UnitStatusInfo info
= {};
6012 path
= unit_dbus_path_from_name(unit
);
6016 r
= acquire_bus(BUS_MANAGER
, &bus
);
6020 r
= sd_bus_call_method(
6022 "org.freedesktop.systemd1",
6024 "org.freedesktop.DBus.Properties",
6030 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
6032 r
= bus_message_map_all_properties(reply
, property_map
, &error
, &info
);
6034 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
6036 return !streq_ptr(info
.load_state
, "not-found") || !streq_ptr(info
.active_state
, "inactive");
6039 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
6040 _cleanup_strv_free_
char **names
= NULL
;
6041 const char *verb
= argv
[0];
6042 UnitFileChange
*changes
= NULL
;
6043 unsigned n_changes
= 0;
6044 int carries_install_info
= -1;
6045 bool ignore_carries_install_info
= arg_quiet
;
6051 r
= mangle_names(strv_skip(argv
, 1), &names
);
6055 r
= enable_sysv_units(verb
, names
);
6059 /* If the operation was fully executed by the SysV compat, let's finish early */
6060 if (strv_isempty(names
)) {
6061 if (arg_no_reload
|| install_client_side())
6063 return daemon_reload(argc
, argv
, userdata
);
6066 if (streq(verb
, "disable")) {
6067 r
= normalize_names(names
, true);
6072 if (install_client_side()) {
6073 UnitFileFlags flags
;
6075 flags
= args_to_flags();
6076 if (streq(verb
, "enable")) {
6077 r
= unit_file_enable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6078 carries_install_info
= r
;
6079 } else if (streq(verb
, "disable"))
6080 r
= unit_file_disable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6081 else if (streq(verb
, "reenable")) {
6082 r
= unit_file_reenable(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6083 carries_install_info
= r
;
6084 } else if (streq(verb
, "link"))
6085 r
= unit_file_link(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6086 else if (streq(verb
, "preset")) {
6087 r
= unit_file_preset(arg_scope
, flags
, arg_root
, names
, arg_preset_mode
, &changes
, &n_changes
);
6088 } else if (streq(verb
, "mask"))
6089 r
= unit_file_mask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6090 else if (streq(verb
, "unmask"))
6091 r
= unit_file_unmask(arg_scope
, flags
, arg_root
, names
, &changes
, &n_changes
);
6092 else if (streq(verb
, "revert"))
6093 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
6095 assert_not_reached("Unknown verb");
6097 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
6102 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6103 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6104 bool expect_carries_install_info
= false;
6105 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
6109 if (STR_IN_SET(verb
, "mask", "unmask")) {
6110 r
= unit_exists(*names
);
6114 log_notice("Unit %s does not exist, proceeding anyway.", *names
);
6117 r
= acquire_bus(BUS_MANAGER
, &bus
);
6121 polkit_agent_open_if_enabled();
6123 if (streq(verb
, "enable")) {
6124 method
= "EnableUnitFiles";
6125 expect_carries_install_info
= true;
6126 } else if (streq(verb
, "disable")) {
6127 method
= "DisableUnitFiles";
6129 } else if (streq(verb
, "reenable")) {
6130 method
= "ReenableUnitFiles";
6131 expect_carries_install_info
= true;
6132 } else if (streq(verb
, "link"))
6133 method
= "LinkUnitFiles";
6134 else if (streq(verb
, "preset")) {
6136 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
6137 method
= "PresetUnitFilesWithMode";
6138 send_preset_mode
= true;
6140 method
= "PresetUnitFiles";
6142 expect_carries_install_info
= true;
6143 ignore_carries_install_info
= true;
6144 } else if (streq(verb
, "mask"))
6145 method
= "MaskUnitFiles";
6146 else if (streq(verb
, "unmask")) {
6147 method
= "UnmaskUnitFiles";
6149 } else if (streq(verb
, "revert")) {
6150 method
= "RevertUnitFiles";
6151 send_runtime
= send_force
= false;
6153 assert_not_reached("Unknown verb");
6155 r
= sd_bus_message_new_method_call(
6158 "org.freedesktop.systemd1",
6159 "/org/freedesktop/systemd1",
6160 "org.freedesktop.systemd1.Manager",
6163 return bus_log_create_error(r
);
6165 r
= sd_bus_message_append_strv(m
, names
);
6167 return bus_log_create_error(r
);
6169 if (send_preset_mode
) {
6170 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
6172 return bus_log_create_error(r
);
6176 r
= sd_bus_message_append(m
, "b", arg_runtime
);
6178 return bus_log_create_error(r
);
6182 r
= sd_bus_message_append(m
, "b", arg_force
);
6184 return bus_log_create_error(r
);
6187 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6189 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
6191 if (expect_carries_install_info
) {
6192 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
6194 return bus_log_parse_error(r
);
6197 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6201 /* Try to reload if enabled */
6203 r
= daemon_reload(argc
, argv
, userdata
);
6208 if (carries_install_info
== 0 && !ignore_carries_install_info
)
6209 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
6210 "settings in the [Install] section, and DefaultInstance for template units).\n"
6211 "This means they are not meant to be enabled using systemctl.\n"
6212 "Possible reasons for having this kind of units are:\n"
6213 "1) A unit may be statically enabled by being symlinked from another unit's\n"
6214 " .wants/ or .requires/ directory.\n"
6215 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
6216 " a requirement dependency on it.\n"
6217 "3) A unit may be started when needed via activation (socket, path, timer,\n"
6218 " D-Bus, udev, scripted systemctl call, ...).\n"
6219 "4) In case of template units, the unit is meant to be enabled with some\n"
6220 " instance name specified.");
6222 if (arg_now
&& STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
6226 r
= acquire_bus(BUS_MANAGER
, &bus
);
6230 len
= strv_length(names
);
6232 char *new_args
[len
+ 2];
6234 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
6235 for (i
= 0; i
< len
; i
++)
6236 new_args
[i
+ 1] = basename(names
[i
]);
6237 new_args
[i
+ 1] = NULL
;
6239 r
= start_unit(len
+ 1, new_args
, userdata
);
6244 unit_file_changes_free(changes
, n_changes
);
6249 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
6250 _cleanup_strv_free_
char **names
= NULL
;
6251 _cleanup_free_
char *target
= NULL
;
6252 const char *verb
= argv
[0];
6253 UnitFileChange
*changes
= NULL
;
6254 unsigned n_changes
= 0;
6261 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
6263 return log_error_errno(r
, "Failed to mangle unit name: %m");
6265 r
= mangle_names(strv_skip(argv
, 2), &names
);
6269 if (streq(verb
, "add-wants"))
6271 else if (streq(verb
, "add-requires"))
6272 dep
= UNIT_REQUIRES
;
6274 assert_not_reached("Unknown verb");
6276 if (install_client_side()) {
6277 r
= unit_file_add_dependency(arg_scope
, args_to_flags(), arg_root
, names
, target
, dep
, &changes
, &n_changes
);
6278 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
6283 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
6284 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6287 r
= acquire_bus(BUS_MANAGER
, &bus
);
6291 polkit_agent_open_if_enabled();
6293 r
= sd_bus_message_new_method_call(
6296 "org.freedesktop.systemd1",
6297 "/org/freedesktop/systemd1",
6298 "org.freedesktop.systemd1.Manager",
6299 "AddDependencyUnitFiles");
6301 return bus_log_create_error(r
);
6303 r
= sd_bus_message_append_strv(m
, names
);
6305 return bus_log_create_error(r
);
6307 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
6309 return bus_log_create_error(r
);
6311 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
6313 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
6315 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6319 if (arg_no_reload
) {
6324 r
= daemon_reload(argc
, argv
, userdata
);
6328 unit_file_changes_free(changes
, n_changes
);
6333 static int preset_all(int argc
, char *argv
[], void *userdata
) {
6334 UnitFileChange
*changes
= NULL
;
6335 unsigned n_changes
= 0;
6338 if (install_client_side()) {
6339 r
= unit_file_preset_all(arg_scope
, args_to_flags(), arg_root
, arg_preset_mode
, &changes
, &n_changes
);
6340 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
6345 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6346 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6349 r
= acquire_bus(BUS_MANAGER
, &bus
);
6353 polkit_agent_open_if_enabled();
6355 r
= sd_bus_call_method(
6357 "org.freedesktop.systemd1",
6358 "/org/freedesktop/systemd1",
6359 "org.freedesktop.systemd1.Manager",
6360 "PresetAllUnitFiles",
6364 unit_file_preset_mode_to_string(arg_preset_mode
),
6368 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
6370 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
6374 if (arg_no_reload
) {
6379 r
= daemon_reload(argc
, argv
, userdata
);
6383 unit_file_changes_free(changes
, n_changes
);
6388 static int show_installation_targets_client_side(const char *name
) {
6389 UnitFileChange
*changes
= NULL
;
6390 unsigned n_changes
= 0, i
;
6391 UnitFileFlags flags
;
6395 p
= STRV_MAKE(name
);
6396 flags
= UNIT_FILE_DRY_RUN
|
6397 (arg_runtime
? UNIT_FILE_RUNTIME
: 0);
6399 r
= unit_file_disable(UNIT_FILE_SYSTEM
, flags
, NULL
, p
, &changes
, &n_changes
);
6401 return log_error_errno(r
, "Failed to get file links for %s: %m", name
);
6403 for (i
= 0; i
< n_changes
; i
++)
6404 if (changes
[i
].type
== UNIT_FILE_UNLINK
)
6405 printf(" %s\n", changes
[i
].path
);
6410 static int show_installation_targets(sd_bus
*bus
, const char *name
) {
6411 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6412 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6416 r
= sd_bus_call_method(
6418 "org.freedesktop.systemd1",
6419 "/org/freedesktop/systemd1",
6420 "org.freedesktop.systemd1.Manager",
6424 "sb", name
, arg_runtime
);
6426 return log_error_errno(r
, "Failed to get unit file links for %s: %s", name
, bus_error_message(&error
, r
));
6428 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
6430 return bus_log_parse_error(r
);
6432 while ((r
= sd_bus_message_read(reply
, "s", &link
)) > 0)
6433 printf(" %s\n", link
);
6436 return bus_log_parse_error(r
);
6438 r
= sd_bus_message_exit_container(reply
);
6440 return bus_log_parse_error(r
);
6445 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
6447 _cleanup_strv_free_
char **names
= NULL
;
6452 r
= mangle_names(strv_skip(argv
, 1), &names
);
6456 r
= enable_sysv_units(argv
[0], names
);
6462 if (install_client_side()) {
6463 STRV_FOREACH(name
, names
) {
6464 UnitFileState state
;
6466 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
6468 return log_error_errno(r
, "Failed to get unit file state for %s: %m", *name
);
6472 UNIT_FILE_ENABLED_RUNTIME
,
6475 UNIT_FILE_GENERATED
))
6479 puts(unit_file_state_to_string(state
));
6481 r
= show_installation_targets_client_side(*name
);
6490 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6493 r
= acquire_bus(BUS_MANAGER
, &bus
);
6497 STRV_FOREACH(name
, names
) {
6498 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6501 r
= sd_bus_call_method(
6503 "org.freedesktop.systemd1",
6504 "/org/freedesktop/systemd1",
6505 "org.freedesktop.systemd1.Manager",
6511 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
6513 r
= sd_bus_message_read(reply
, "s", &s
);
6515 return bus_log_parse_error(r
);
6517 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6523 r
= show_installation_targets(bus
, *name
);
6531 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
6534 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
6535 _cleanup_free_
char *state
= NULL
;
6539 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
6542 return EXIT_FAILURE
;
6545 r
= acquire_bus(BUS_MANAGER
, &bus
);
6549 r
= sd_bus_get_property_string(
6551 "org.freedesktop.systemd1",
6552 "/org/freedesktop/systemd1",
6553 "org.freedesktop.systemd1.Manager",
6566 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
6569 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
6570 _cleanup_free_
char *t
= NULL
;
6574 assert(original_path
);
6577 r
= tempfn_random(new_path
, NULL
, &t
);
6579 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
6581 r
= mkdir_parents(new_path
, 0755);
6583 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
6585 r
= copy_file(original_path
, t
, 0, 0644, 0, COPY_REFLINK
);
6590 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
6593 return log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", new_path
);
6601 static int get_file_to_edit(
6602 const LookupPaths
*paths
,
6606 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
6611 path
= strjoin(paths
->persistent_config
, "/", name
);
6616 run
= strjoin(paths
->runtime_config
, "/", name
);
6622 if (access(path
, F_OK
) >= 0) {
6623 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
6637 static int unit_file_create_new(
6638 const LookupPaths
*paths
,
6639 const char *unit_name
,
6641 char **ret_new_path
,
6642 char **ret_tmp_path
) {
6644 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6648 assert(ret_new_path
);
6649 assert(ret_tmp_path
);
6651 ending
= strjoina(unit_name
, suffix
);
6652 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
6656 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6662 *ret_new_path
= tmp_new_path
;
6663 *ret_tmp_path
= tmp_tmp_path
;
6668 static int unit_file_create_copy(
6669 const LookupPaths
*paths
,
6670 const char *unit_name
,
6671 const char *fragment_path
,
6672 char **ret_new_path
,
6673 char **ret_tmp_path
) {
6675 char *tmp_new_path
, *tmp_tmp_path
;
6678 assert(fragment_path
);
6680 assert(ret_new_path
);
6681 assert(ret_tmp_path
);
6683 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6687 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6690 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6695 if (response
!= 'y') {
6696 log_warning("%s ignored", unit_name
);
6698 return -EKEYREJECTED
;
6702 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6708 *ret_new_path
= tmp_new_path
;
6709 *ret_tmp_path
= tmp_tmp_path
;
6714 static int run_editor(char **paths
) {
6722 return log_error_errno(errno
, "Failed to fork: %m");
6726 char *editor
, **editor_args
= NULL
;
6727 char **tmp_path
, **original_path
, *p
;
6728 unsigned n_editor_args
= 0, i
= 1;
6731 (void) reset_all_signal_handlers();
6732 (void) reset_signal_mask();
6734 argc
= strv_length(paths
)/2 + 1;
6736 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6737 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6738 * we try to execute well known editors
6740 editor
= getenv("SYSTEMD_EDITOR");
6742 editor
= getenv("EDITOR");
6744 editor
= getenv("VISUAL");
6746 if (!isempty(editor
)) {
6747 editor_args
= strv_split(editor
, WHITESPACE
);
6750 _exit(EXIT_FAILURE
);
6752 n_editor_args
= strv_length(editor_args
);
6753 argc
+= n_editor_args
- 1;
6755 args
= newa(const char*, argc
+ 1);
6757 if (n_editor_args
> 0) {
6758 args
[0] = editor_args
[0];
6759 for (; i
< n_editor_args
; i
++)
6760 args
[i
] = editor_args
[i
];
6763 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6764 args
[i
] = *tmp_path
;
6769 if (n_editor_args
> 0)
6770 execvp(args
[0], (char* const*) args
);
6772 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6774 execvp(p
, (char* const*) args
);
6775 /* We do not fail if the editor doesn't exist
6776 * because we want to try each one of them before
6779 if (errno
!= ENOENT
) {
6780 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6781 _exit(EXIT_FAILURE
);
6785 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6786 _exit(EXIT_FAILURE
);
6789 r
= wait_for_terminate_and_warn("editor", pid
, true);
6791 return log_error_errno(r
, "Failed to wait for child: %m");
6796 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6797 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6804 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6808 STRV_FOREACH(name
, names
) {
6809 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
, *tmp_name
= NULL
;
6810 const char *unit_name
;
6812 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6820 log_error("Run 'systemctl edit%s --force %s' to create a new unit.",
6821 arg_scope
== UNIT_FILE_GLOBAL
? " --global" :
6822 arg_scope
== UNIT_FILE_USER
? " --user" : "",
6827 /* Create a new unit from scratch */
6829 r
= unit_file_create_new(&lp
, unit_name
,
6830 arg_full
? NULL
: ".d/override.conf",
6831 &new_path
, &tmp_path
);
6835 unit_name
= basename(path
);
6836 /* We follow unit aliases, but we need to propagate the instance */
6837 if (unit_name_is_valid(*name
, UNIT_NAME_INSTANCE
) &&
6838 unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
6839 _cleanup_free_
char *instance
= NULL
;
6841 r
= unit_name_to_instance(*name
, &instance
);
6845 r
= unit_name_replace_instance(unit_name
, instance
, &tmp_name
);
6849 unit_name
= tmp_name
;
6853 r
= unit_file_create_copy(&lp
, unit_name
, path
, &new_path
, &tmp_path
);
6855 r
= unit_file_create_new(&lp
, unit_name
, ".d/override.conf", &new_path
, &tmp_path
);
6860 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6863 new_path
= tmp_path
= NULL
;
6869 static int edit(int argc
, char *argv
[], void *userdata
) {
6870 _cleanup_strv_free_
char **names
= NULL
;
6871 _cleanup_strv_free_
char **paths
= NULL
;
6872 char **original
, **tmp
;
6877 log_error("Cannot edit units if not on a tty.");
6881 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6882 log_error("Cannot edit units remotely.");
6886 r
= acquire_bus(BUS_MANAGER
, &bus
);
6890 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6892 return log_error_errno(r
, "Failed to expand names: %m");
6894 r
= find_paths_to_edit(bus
, names
, &paths
);
6898 if (strv_isempty(paths
))
6901 r
= run_editor(paths
);
6905 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6906 /* If the temporary file is empty we ignore it. It's
6907 * useful if the user wants to cancel its modification
6909 if (null_or_empty_path(*tmp
)) {
6910 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6914 r
= rename(*tmp
, *original
);
6916 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6923 if (!arg_no_reload
&& !install_client_side())
6924 r
= daemon_reload(argc
, argv
, userdata
);
6927 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6928 (void) unlink(*tmp
);
6930 /* Removing empty dropin dirs */
6932 _cleanup_free_
char *dir
;
6934 dir
= dirname_malloc(*original
);
6938 /* no need to check if the dir is empty, rmdir
6939 * does nothing if it is not the case.
6948 static void systemctl_help(void) {
6950 pager_open(arg_no_pager
, false);
6952 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6953 "Query or send control commands to the systemd manager.\n\n"
6954 " -h --help Show this help\n"
6955 " --version Show package version\n"
6956 " --system Connect to system manager\n"
6957 " --user Connect to user service manager\n"
6958 " -H --host=[USER@]HOST\n"
6959 " Operate on remote host\n"
6960 " -M --machine=CONTAINER\n"
6961 " Operate on local container\n"
6962 " -t --type=TYPE List units of a particular type\n"
6963 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6964 " -p --property=NAME Show only properties by this name\n"
6965 " -a --all Show all properties/all units currently in memory,\n"
6966 " including dead/empty ones. To list all units installed on\n"
6967 " the system, use the 'list-unit-files' command instead.\n"
6968 " --failed Same as --state=failed\n"
6969 " -l --full Don't ellipsize unit names on output\n"
6970 " -r --recursive Show unit list of host and local containers\n"
6971 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6972 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6973 " queueing a new job\n"
6974 " --show-types When showing sockets, explicitly show their type\n"
6975 " --value When showing properties, only print the value\n"
6976 " -i --ignore-inhibitors\n"
6977 " When shutting down or sleeping, ignore inhibitors\n"
6978 " --kill-who=WHO Who to send signal to\n"
6979 " -s --signal=SIGNAL Which signal to send\n"
6980 " --now Start or stop unit in addition to enabling or disabling it\n"
6981 " -q --quiet Suppress output\n"
6982 " --wait For (re)start, wait until service stopped again\n"
6983 " --no-block Do not wait until operation finished\n"
6984 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6985 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6986 " --no-legend Do not print a legend (column headers and hints)\n"
6987 " --no-pager Do not pipe output into a pager\n"
6988 " --no-ask-password\n"
6989 " Do not ask for system passwords\n"
6990 " --global Enable/disable unit files globally\n"
6991 " --runtime Enable unit files only temporarily until next reboot\n"
6992 " -f --force When enabling unit files, override existing symlinks\n"
6993 " When shutting down, execute action immediately\n"
6994 " --preset-mode= Apply only enable, only disable, or all presets\n"
6995 " --root=PATH Enable unit files in the specified root directory\n"
6996 " -n --lines=INTEGER Number of journal entries to show\n"
6997 " -o --output=STRING Change journal output mode (short, short-precise,\n"
6998 " short-iso, short-full, short-monotonic, short-unix,\n"
6999 " verbose, export, json, json-pretty, json-sse, cat)\n"
7000 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
7001 " --plain Print unit dependencies as a list instead of a tree\n\n"
7003 " list-units [PATTERN...] List units currently in memory\n"
7004 " list-sockets [PATTERN...] List socket units currently in memory, ordered\n"
7006 " list-timers [PATTERN...] List timer units currently in memory, ordered\n"
7008 " start NAME... Start (activate) one or more units\n"
7009 " stop NAME... Stop (deactivate) one or more units\n"
7010 " reload NAME... Reload one or more units\n"
7011 " restart NAME... Start or restart one or more units\n"
7012 " try-restart NAME... Restart one or more units if active\n"
7013 " reload-or-restart NAME... Reload one or more units if possible,\n"
7014 " otherwise start or restart\n"
7015 " try-reload-or-restart NAME... If active, reload one or more units,\n"
7016 " if supported, otherwise restart\n"
7017 " isolate NAME Start one unit and stop all others\n"
7018 " kill NAME... Send signal to processes of a unit\n"
7019 " is-active PATTERN... Check whether units are active\n"
7020 " is-failed PATTERN... Check whether units are failed\n"
7021 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
7022 " show [PATTERN...|JOB...] Show properties of one or more\n"
7023 " units/jobs or the manager\n"
7024 " cat PATTERN... Show files and drop-ins of one or more units\n"
7025 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
7026 " help PATTERN...|PID... Show manual for one or more units\n"
7027 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
7029 " list-dependencies [NAME] Recursively show units which are required\n"
7030 " or wanted by this unit or by which this\n"
7031 " unit is required or wanted\n\n"
7032 "Unit File Commands:\n"
7033 " list-unit-files [PATTERN...] List installed unit files\n"
7034 " enable [NAME...|PATH...] Enable one or more unit files\n"
7035 " disable NAME... Disable one or more unit files\n"
7036 " reenable NAME... Reenable one or more unit files\n"
7037 " preset NAME... Enable/disable one or more unit files\n"
7038 " based on preset configuration\n"
7039 " preset-all Enable/disable all unit files based on\n"
7040 " preset configuration\n"
7041 " is-enabled NAME... Check whether unit files are enabled\n"
7042 " mask NAME... Mask one or more units\n"
7043 " unmask NAME... Unmask one or more units\n"
7044 " link PATH... Link one or more units files into\n"
7045 " the search path\n"
7046 " revert NAME... Revert one or more unit files to vendor\n"
7048 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
7049 " on specified one or more units\n"
7050 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
7051 " on specified one or more units\n"
7052 " edit NAME... Edit one or more unit files\n"
7053 " get-default Get the name of the default target\n"
7054 " set-default NAME Set the default target\n\n"
7055 "Machine Commands:\n"
7056 " list-machines [PATTERN...] List local containers and host\n\n"
7058 " list-jobs [PATTERN...] List jobs\n"
7059 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
7060 "Environment Commands:\n"
7061 " show-environment Dump environment\n"
7062 " set-environment NAME=VALUE... Set one or more environment variables\n"
7063 " unset-environment NAME... Unset one or more environment variables\n"
7064 " import-environment [NAME...] Import all or some environment variables\n\n"
7065 "Manager Lifecycle Commands:\n"
7066 " daemon-reload Reload systemd manager configuration\n"
7067 " daemon-reexec Reexecute systemd manager\n\n"
7068 "System Commands:\n"
7069 " is-system-running Check whether system is fully running\n"
7070 " default Enter system default mode\n"
7071 " rescue Enter system rescue mode\n"
7072 " emergency Enter system emergency mode\n"
7073 " halt Shut down and halt the system\n"
7074 " poweroff Shut down and power-off the system\n"
7075 " reboot [ARG] Shut down and reboot the system\n"
7076 " kexec Shut down and reboot the system with kexec\n"
7077 " exit [EXIT_CODE] Request user instance or container exit\n"
7078 " switch-root ROOT [INIT] Change to a different root file system\n"
7079 " suspend Suspend the system\n"
7080 " hibernate Hibernate the system\n"
7081 " hybrid-sleep Hibernate and suspend the system\n",
7082 program_invocation_short_name
);
7085 static void halt_help(void) {
7086 printf("%s [OPTIONS...]%s\n\n"
7087 "%s the system.\n\n"
7088 " --help Show this help\n"
7089 " --halt Halt the machine\n"
7090 " -p --poweroff Switch off the machine\n"
7091 " --reboot Reboot the machine\n"
7092 " -f --force Force immediate halt/power-off/reboot\n"
7093 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
7094 " -d --no-wtmp Don't write wtmp record\n"
7095 " --no-wall Don't send wall message before halt/power-off/reboot\n",
7096 program_invocation_short_name
,
7097 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
7098 arg_action
== ACTION_REBOOT
? "Reboot" :
7099 arg_action
== ACTION_POWEROFF
? "Power off" :
7103 static void shutdown_help(void) {
7104 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
7105 "Shut down the system.\n\n"
7106 " --help Show this help\n"
7107 " -H --halt Halt the machine\n"
7108 " -P --poweroff Power-off the machine\n"
7109 " -r --reboot Reboot the machine\n"
7110 " -h Equivalent to --poweroff, overridden by --halt\n"
7111 " -k Don't halt/power-off/reboot, just send warnings\n"
7112 " --no-wall Don't send wall message before halt/power-off/reboot\n"
7113 " -c Cancel a pending shutdown\n",
7114 program_invocation_short_name
);
7117 static void telinit_help(void) {
7118 printf("%s [OPTIONS...] {COMMAND}\n\n"
7119 "Send control commands to the init daemon.\n\n"
7120 " --help Show this help\n"
7121 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
7123 " 0 Power-off the machine\n"
7124 " 6 Reboot the machine\n"
7125 " 2, 3, 4, 5 Start runlevelX.target unit\n"
7126 " 1, s, S Enter rescue mode\n"
7127 " q, Q Reload init daemon configuration\n"
7128 " u, U Reexecute init daemon\n",
7129 program_invocation_short_name
);
7132 static void runlevel_help(void) {
7133 printf("%s [OPTIONS...]\n\n"
7134 "Prints the previous and current runlevel of the init system.\n\n"
7135 " --help Show this help\n",
7136 program_invocation_short_name
);
7139 static void help_types(void) {
7143 puts("Available unit types:");
7144 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
7145 puts(unit_type_to_string(i
));
7148 static void help_states(void) {
7152 puts("Available unit load states:");
7153 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
7154 puts(unit_load_state_to_string(i
));
7157 puts("\nAvailable unit active states:");
7158 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
7159 puts(unit_active_state_to_string(i
));
7162 puts("\nAvailable automount unit substates:");
7163 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
7164 puts(automount_state_to_string(i
));
7167 puts("\nAvailable busname unit substates:");
7168 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
7169 puts(busname_state_to_string(i
));
7172 puts("\nAvailable device unit substates:");
7173 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
7174 puts(device_state_to_string(i
));
7177 puts("\nAvailable mount unit substates:");
7178 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
7179 puts(mount_state_to_string(i
));
7182 puts("\nAvailable path unit substates:");
7183 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
7184 puts(path_state_to_string(i
));
7187 puts("\nAvailable scope unit substates:");
7188 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
7189 puts(scope_state_to_string(i
));
7192 puts("\nAvailable service unit substates:");
7193 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
7194 puts(service_state_to_string(i
));
7197 puts("\nAvailable slice unit substates:");
7198 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
7199 puts(slice_state_to_string(i
));
7202 puts("\nAvailable socket unit substates:");
7203 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
7204 puts(socket_state_to_string(i
));
7207 puts("\nAvailable swap unit substates:");
7208 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
7209 puts(swap_state_to_string(i
));
7212 puts("\nAvailable target unit substates:");
7213 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
7214 puts(target_state_to_string(i
));
7217 puts("\nAvailable timer unit substates:");
7218 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
7219 puts(timer_state_to_string(i
));
7222 static int systemctl_parse_argv(int argc
, char *argv
[]) {
7231 ARG_IGNORE_DEPENDENCIES
,
7244 ARG_NO_ASK_PASSWORD
,
7258 static const struct option options
[] = {
7259 { "help", no_argument
, NULL
, 'h' },
7260 { "version", no_argument
, NULL
, ARG_VERSION
},
7261 { "type", required_argument
, NULL
, 't' },
7262 { "property", required_argument
, NULL
, 'p' },
7263 { "all", no_argument
, NULL
, 'a' },
7264 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
7265 { "after", no_argument
, NULL
, ARG_AFTER
},
7266 { "before", no_argument
, NULL
, ARG_BEFORE
},
7267 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
7268 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
7269 { "full", no_argument
, NULL
, 'l' },
7270 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
7271 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
7272 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
7273 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
7274 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
7275 { "value", no_argument
, NULL
, ARG_VALUE
},
7276 { "user", no_argument
, NULL
, ARG_USER
},
7277 { "system", no_argument
, NULL
, ARG_SYSTEM
},
7278 { "global", no_argument
, NULL
, ARG_GLOBAL
},
7279 { "wait", no_argument
, NULL
, ARG_WAIT
},
7280 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
7281 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
7282 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
7283 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7284 { "quiet", no_argument
, NULL
, 'q' },
7285 { "root", required_argument
, NULL
, ARG_ROOT
},
7286 { "force", no_argument
, NULL
, ARG_FORCE
},
7287 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
7288 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
7289 { "signal", required_argument
, NULL
, 's' },
7290 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
7291 { "host", required_argument
, NULL
, 'H' },
7292 { "machine", required_argument
, NULL
, 'M' },
7293 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
7294 { "lines", required_argument
, NULL
, 'n' },
7295 { "output", required_argument
, NULL
, 'o' },
7296 { "plain", no_argument
, NULL
, ARG_PLAIN
},
7297 { "state", required_argument
, NULL
, ARG_STATE
},
7298 { "recursive", no_argument
, NULL
, 'r' },
7299 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
7300 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
7301 { "now", no_argument
, NULL
, ARG_NOW
},
7302 { "message", required_argument
, NULL
, ARG_MESSAGE
},
7312 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
7313 arg_ask_password
= true;
7315 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
7327 if (isempty(optarg
)) {
7328 log_error("--type requires arguments.");
7332 for (p
= optarg
;;) {
7333 _cleanup_free_
char *type
= NULL
;
7335 r
= extract_first_word(&p
, &type
, ",", 0);
7337 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
7341 if (streq(type
, "help")) {
7346 if (unit_type_from_string(type
) >= 0) {
7347 if (strv_push(&arg_types
, type
) < 0)
7353 /* It's much nicer to use --state= for
7354 * load states, but let's support this
7355 * in --types= too for compatibility
7356 * with old versions */
7357 if (unit_load_state_from_string(type
) >= 0) {
7358 if (strv_push(&arg_states
, type
) < 0)
7364 log_error("Unknown unit type or load state '%s'.", type
);
7365 log_info("Use -t help to see a list of allowed values.");
7373 /* Make sure that if the empty property list
7374 was specified, we won't show any properties. */
7375 if (isempty(optarg
) && !arg_properties
) {
7376 arg_properties
= new0(char*, 1);
7377 if (!arg_properties
)
7380 for (p
= optarg
;;) {
7381 _cleanup_free_
char *prop
= NULL
;
7383 r
= extract_first_word(&p
, &prop
, ",", 0);
7385 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
7389 if (strv_push(&arg_properties
, prop
) < 0)
7395 /* If the user asked for a particular
7396 * property, show it to him, even if it is
7408 arg_dependency
= DEPENDENCY_REVERSE
;
7412 arg_dependency
= DEPENDENCY_AFTER
;
7413 arg_jobs_after
= true;
7417 arg_dependency
= DEPENDENCY_BEFORE
;
7418 arg_jobs_before
= true;
7421 case ARG_SHOW_TYPES
:
7422 arg_show_types
= true;
7430 arg_job_mode
= optarg
;
7434 arg_job_mode
= "fail";
7437 case ARG_IRREVERSIBLE
:
7438 arg_job_mode
= "replace-irreversibly";
7441 case ARG_IGNORE_DEPENDENCIES
:
7442 arg_job_mode
= "ignore-dependencies";
7446 arg_scope
= UNIT_FILE_USER
;
7450 arg_scope
= UNIT_FILE_SYSTEM
;
7454 arg_scope
= UNIT_FILE_GLOBAL
;
7462 arg_no_block
= true;
7466 arg_no_legend
= true;
7470 arg_no_pager
= true;
7478 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
7488 if (strv_extend(&arg_states
, "failed") < 0)
7506 arg_no_reload
= true;
7510 arg_kill_who
= optarg
;
7514 arg_signal
= signal_from_string_try_harder(optarg
);
7515 if (arg_signal
< 0) {
7516 log_error("Failed to parse signal string %s.", optarg
);
7521 case ARG_NO_ASK_PASSWORD
:
7522 arg_ask_password
= false;
7526 arg_transport
= BUS_TRANSPORT_REMOTE
;
7531 arg_transport
= BUS_TRANSPORT_MACHINE
;
7540 if (safe_atou(optarg
, &arg_lines
) < 0) {
7541 log_error("Failed to parse lines '%s'", optarg
);
7547 arg_output
= output_mode_from_string(optarg
);
7548 if (arg_output
< 0) {
7549 log_error("Unknown output '%s'.", optarg
);
7555 arg_ignore_inhibitors
= true;
7562 case ARG_FIRMWARE_SETUP
:
7563 arg_firmware_setup
= true;
7567 if (isempty(optarg
)) {
7568 log_error("--signal requires arguments.");
7572 for (p
= optarg
;;) {
7573 _cleanup_free_
char *s
= NULL
;
7575 r
= extract_first_word(&p
, &s
, ",", 0);
7577 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
7581 if (streq(s
, "help")) {
7586 if (strv_push(&arg_states
, s
) < 0)
7595 if (geteuid() != 0) {
7596 log_error("--recursive requires root privileges.");
7600 arg_recursive
= true;
7603 case ARG_PRESET_MODE
:
7605 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
7606 if (arg_preset_mode
< 0) {
7607 log_error("Failed to parse preset mode: %s.", optarg
);
7618 if (strv_extend(&arg_wall
, optarg
) < 0)
7626 assert_not_reached("Unhandled option");
7629 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
7630 log_error("Cannot access user instance remotely.");
7634 if (arg_wait
&& arg_no_block
) {
7635 log_error("--wait may not be combined with --no-block.");
7642 static int halt_parse_argv(int argc
, char *argv
[]) {
7651 static const struct option options
[] = {
7652 { "help", no_argument
, NULL
, ARG_HELP
},
7653 { "halt", no_argument
, NULL
, ARG_HALT
},
7654 { "poweroff", no_argument
, NULL
, 'p' },
7655 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
7656 { "force", no_argument
, NULL
, 'f' },
7657 { "wtmp-only", no_argument
, NULL
, 'w' },
7658 { "no-wtmp", no_argument
, NULL
, 'd' },
7659 { "no-sync", no_argument
, NULL
, 'n' },
7660 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7669 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
7670 if (runlevel
== '0' || runlevel
== '6')
7673 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
7681 arg_action
= ACTION_HALT
;
7685 if (arg_action
!= ACTION_REBOOT
)
7686 arg_action
= ACTION_POWEROFF
;
7690 arg_action
= ACTION_REBOOT
;
7715 /* Compatibility nops */
7722 assert_not_reached("Unhandled option");
7725 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7726 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7729 } else if (optind
< argc
) {
7730 log_error("Too many arguments.");
7737 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7741 if (streq(t
, "now"))
7743 else if (!strchr(t
, ':')) {
7746 if (safe_atou64(t
, &u
) < 0)
7749 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7758 hour
= strtol(t
, &e
, 10);
7759 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7762 minute
= strtol(e
+1, &e
, 10);
7763 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7766 n
= now(CLOCK_REALTIME
);
7767 s
= (time_t) (n
/ USEC_PER_SEC
);
7769 assert_se(localtime_r(&s
, &tm
));
7771 tm
.tm_hour
= (int) hour
;
7772 tm
.tm_min
= (int) minute
;
7775 assert_se(s
= mktime(&tm
));
7777 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7780 *_u
+= USEC_PER_DAY
;
7786 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7793 static const struct option options
[] = {
7794 { "help", no_argument
, NULL
, ARG_HELP
},
7795 { "halt", no_argument
, NULL
, 'H' },
7796 { "poweroff", no_argument
, NULL
, 'P' },
7797 { "reboot", no_argument
, NULL
, 'r' },
7798 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7799 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7809 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7817 arg_action
= ACTION_HALT
;
7821 arg_action
= ACTION_POWEROFF
;
7826 arg_action
= ACTION_KEXEC
;
7828 arg_action
= ACTION_REBOOT
;
7832 arg_action
= ACTION_KEXEC
;
7836 if (arg_action
!= ACTION_HALT
)
7837 arg_action
= ACTION_POWEROFF
;
7852 /* Compatibility nops */
7856 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7863 assert_not_reached("Unhandled option");
7866 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7867 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7869 log_error("Failed to parse time specification: %s", argv
[optind
]);
7873 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7875 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7876 /* No time argument for shutdown cancel */
7877 wall
= argv
+ optind
;
7878 else if (argc
> optind
+ 1)
7879 /* We skip the time argument */
7880 wall
= argv
+ optind
+ 1;
7883 arg_wall
= strv_copy(wall
);
7893 static int telinit_parse_argv(int argc
, char *argv
[]) {
7900 static const struct option options
[] = {
7901 { "help", no_argument
, NULL
, ARG_HELP
},
7902 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7906 static const struct {
7910 { '0', ACTION_POWEROFF
},
7911 { '6', ACTION_REBOOT
},
7912 { '1', ACTION_RESCUE
},
7913 { '2', ACTION_RUNLEVEL2
},
7914 { '3', ACTION_RUNLEVEL3
},
7915 { '4', ACTION_RUNLEVEL4
},
7916 { '5', ACTION_RUNLEVEL5
},
7917 { 's', ACTION_RESCUE
},
7918 { 'S', ACTION_RESCUE
},
7919 { 'q', ACTION_RELOAD
},
7920 { 'Q', ACTION_RELOAD
},
7921 { 'u', ACTION_REEXEC
},
7922 { 'U', ACTION_REEXEC
}
7931 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7946 assert_not_reached("Unhandled option");
7949 if (optind
>= argc
) {
7950 log_error("%s: required argument missing.", program_invocation_short_name
);
7954 if (optind
+ 1 < argc
) {
7955 log_error("Too many arguments.");
7959 if (strlen(argv
[optind
]) != 1) {
7960 log_error("Expected single character argument.");
7964 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7965 if (table
[i
].from
== argv
[optind
][0])
7968 if (i
>= ELEMENTSOF(table
)) {
7969 log_error("Unknown command '%s'.", argv
[optind
]);
7973 arg_action
= table
[i
].to
;
7980 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7986 static const struct option options
[] = {
7987 { "help", no_argument
, NULL
, ARG_HELP
},
7996 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
8007 assert_not_reached("Unhandled option");
8010 if (optind
< argc
) {
8011 log_error("Too many arguments.");
8018 static int parse_argv(int argc
, char *argv
[]) {
8022 if (program_invocation_short_name
) {
8024 if (strstr(program_invocation_short_name
, "halt")) {
8025 arg_action
= ACTION_HALT
;
8026 return halt_parse_argv(argc
, argv
);
8027 } else if (strstr(program_invocation_short_name
, "poweroff")) {
8028 arg_action
= ACTION_POWEROFF
;
8029 return halt_parse_argv(argc
, argv
);
8030 } else if (strstr(program_invocation_short_name
, "reboot")) {
8032 arg_action
= ACTION_KEXEC
;
8034 arg_action
= ACTION_REBOOT
;
8035 return halt_parse_argv(argc
, argv
);
8036 } else if (strstr(program_invocation_short_name
, "shutdown")) {
8037 arg_action
= ACTION_POWEROFF
;
8038 return shutdown_parse_argv(argc
, argv
);
8039 } else if (strstr(program_invocation_short_name
, "init")) {
8041 if (sd_booted() > 0) {
8042 arg_action
= _ACTION_INVALID
;
8043 return telinit_parse_argv(argc
, argv
);
8045 /* Hmm, so some other init system is
8046 * running, we need to forward this
8047 * request to it. For now we simply
8048 * guess that it is Upstart. */
8050 execv(TELINIT
, argv
);
8052 log_error("Couldn't find an alternative telinit implementation to spawn.");
8056 } else if (strstr(program_invocation_short_name
, "runlevel")) {
8057 arg_action
= ACTION_RUNLEVEL
;
8058 return runlevel_parse_argv(argc
, argv
);
8062 arg_action
= ACTION_SYSTEMCTL
;
8063 return systemctl_parse_argv(argc
, argv
);
8066 #ifdef HAVE_SYSV_COMPAT
8067 _pure_
static int action_to_runlevel(void) {
8069 static const char table
[_ACTION_MAX
] = {
8070 [ACTION_HALT
] = '0',
8071 [ACTION_POWEROFF
] = '0',
8072 [ACTION_REBOOT
] = '6',
8073 [ACTION_RUNLEVEL2
] = '2',
8074 [ACTION_RUNLEVEL3
] = '3',
8075 [ACTION_RUNLEVEL4
] = '4',
8076 [ACTION_RUNLEVEL5
] = '5',
8077 [ACTION_RESCUE
] = '1'
8080 assert(arg_action
< _ACTION_MAX
);
8082 return table
[arg_action
];
8086 static int talk_initctl(void) {
8087 #ifdef HAVE_SYSV_COMPAT
8088 struct init_request request
= {
8089 .magic
= INIT_MAGIC
,
8091 .cmd
= INIT_CMD_RUNLVL
8094 _cleanup_close_
int fd
= -1;
8098 rl
= action_to_runlevel();
8102 request
.runlevel
= rl
;
8104 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
8106 if (errno
== ENOENT
)
8109 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
8112 r
= loop_write(fd
, &request
, sizeof(request
), false);
8114 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
8122 static int systemctl_main(int argc
, char *argv
[]) {
8124 static const Verb verbs
[] = {
8125 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
8126 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
8127 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
8128 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
8129 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
8130 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
8131 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, trivial_method
},
8132 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
8133 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8134 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8135 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8136 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8137 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8138 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8139 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8140 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
8141 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
8142 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
8143 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
8144 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
8145 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
8146 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
8147 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8148 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
8149 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
8150 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8151 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
8152 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8153 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
8154 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8155 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
8156 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
8157 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8158 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
8159 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
8160 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8161 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8162 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_system_special
},
8163 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8164 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8165 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8166 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8167 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
8168 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8169 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
8170 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
8171 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
8172 { "enable", 2, VERB_ANY
, 0, enable_unit
},
8173 { "disable", 2, VERB_ANY
, 0, enable_unit
},
8174 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
8175 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
8176 { "preset", 2, VERB_ANY
, 0, enable_unit
},
8177 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
8178 { "mask", 2, VERB_ANY
, 0, enable_unit
},
8179 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
8180 { "link", 2, VERB_ANY
, 0, enable_unit
},
8181 { "revert", 2, VERB_ANY
, 0, enable_unit
},
8182 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
8183 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
8184 { "set-default", 2, 2, 0, set_default
},
8185 { "get-default", VERB_ANY
, 1, 0, get_default
},
8186 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
8187 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
8188 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
8189 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
8190 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
8194 return dispatch_verb(argc
, argv
, verbs
, NULL
);
8197 static int reload_with_fallback(void) {
8199 /* First, try systemd via D-Bus. */
8200 if (daemon_reload(0, NULL
, NULL
) >= 0)
8203 /* Nothing else worked, so let's try signals */
8204 assert(IN_SET(arg_action
, ACTION_RELOAD
, ACTION_REEXEC
));
8206 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
8207 return log_error_errno(errno
, "kill() failed: %m");
8212 static int start_with_fallback(void) {
8214 /* First, try systemd via D-Bus. */
8215 if (start_unit(0, NULL
, NULL
) >= 0)
8218 /* Nothing else worked, so let's try /dev/initctl */
8219 if (talk_initctl() > 0)
8222 log_error("Failed to talk to init daemon.");
8226 static int halt_now(enum action a
) {
8229 /* The kernel will automaticall flush ATA disks and suchlike
8230 * on reboot(), but the file systems need to be synce'd
8231 * explicitly in advance. */
8235 /* Make sure C-A-D is handled by the kernel from this point
8237 (void) reboot(RB_ENABLE_CAD
);
8242 log_info("Halting.");
8243 (void) reboot(RB_HALT_SYSTEM
);
8246 case ACTION_POWEROFF
:
8247 log_info("Powering off.");
8248 (void) reboot(RB_POWER_OFF
);
8252 case ACTION_REBOOT
: {
8253 _cleanup_free_
char *param
= NULL
;
8255 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
8257 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
8259 if (!isempty(param
)) {
8260 log_info("Rebooting with argument '%s'.", param
);
8261 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
8262 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
8265 log_info("Rebooting.");
8266 (void) reboot(RB_AUTOBOOT
);
8271 assert_not_reached("Unknown action.");
8275 static int logind_schedule_shutdown(void) {
8278 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8279 char date
[FORMAT_TIMESTAMP_MAX
];
8284 r
= acquire_bus(BUS_FULL
, &bus
);
8288 switch (arg_action
) {
8292 case ACTION_POWEROFF
:
8293 action
= "poweroff";
8308 action
= strjoina("dry-", action
);
8310 (void) logind_set_wall_message();
8312 r
= sd_bus_call_method(
8314 "org.freedesktop.login1",
8315 "/org/freedesktop/login1",
8316 "org.freedesktop.login1.Manager",
8324 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
8326 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
8329 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
8334 static int halt_main(void) {
8337 r
= logind_check_inhibitors(arg_action
);
8342 return logind_schedule_shutdown();
8344 if (geteuid() != 0) {
8345 if (arg_dry
|| arg_force
> 0) {
8346 log_error("Must be root.");
8350 /* Try logind if we are a normal user and no special
8351 * mode applies. Maybe PolicyKit allows us to shutdown
8353 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
8354 r
= logind_reboot(arg_action
);
8357 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
8358 /* requested operation is not
8359 * supported on the local system or
8360 * already in progress */
8362 /* on all other errors, try low-level operation */
8366 if (!arg_dry
&& !arg_force
)
8367 return start_with_fallback();
8369 assert(geteuid() == 0);
8372 if (sd_booted() > 0)
8373 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
8375 r
= utmp_put_shutdown();
8377 log_warning_errno(r
, "Failed to write utmp record: %m");
8384 r
= halt_now(arg_action
);
8385 return log_error_errno(r
, "Failed to reboot: %m");
8388 static int runlevel_main(void) {
8389 int r
, runlevel
, previous
;
8391 r
= utmp_get_runlevel(&runlevel
, &previous
);
8398 previous
<= 0 ? 'N' : previous
,
8399 runlevel
<= 0 ? 'N' : runlevel
);
8404 static int logind_cancel_shutdown(void) {
8406 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
8410 r
= acquire_bus(BUS_FULL
, &bus
);
8414 (void) logind_set_wall_message();
8416 r
= sd_bus_call_method(
8418 "org.freedesktop.login1",
8419 "/org/freedesktop/login1",
8420 "org.freedesktop.login1.Manager",
8421 "CancelScheduledShutdown",
8425 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
8429 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
8434 int main(int argc
, char*argv
[]) {
8437 argv_cmdline
= argv
[0];
8439 setlocale(LC_ALL
, "");
8440 log_parse_environment();
8444 /* Explicitly not on_tty() to avoid setting cached value.
8445 * This becomes relevant for piping output which might be
8447 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
8449 r
= parse_argv(argc
, argv
);
8453 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
8454 log_info("Running in chroot, ignoring request.");
8459 /* systemctl_main() will print an error message for the bus
8460 * connection, but only if it needs to */
8462 switch (arg_action
) {
8464 case ACTION_SYSTEMCTL
:
8465 r
= systemctl_main(argc
, argv
);
8469 case ACTION_POWEROFF
:
8475 case ACTION_RUNLEVEL2
:
8476 case ACTION_RUNLEVEL3
:
8477 case ACTION_RUNLEVEL4
:
8478 case ACTION_RUNLEVEL5
:
8480 case ACTION_EMERGENCY
:
8481 case ACTION_DEFAULT
:
8482 r
= start_with_fallback();
8487 r
= reload_with_fallback();
8490 case ACTION_CANCEL_SHUTDOWN
:
8491 r
= logind_cancel_shutdown();
8494 case ACTION_RUNLEVEL
:
8495 r
= runlevel_main();
8498 case _ACTION_INVALID
:
8500 assert_not_reached("Unknown action");
8507 ask_password_agent_close();
8508 polkit_agent_close();
8510 strv_free(arg_types
);
8511 strv_free(arg_states
);
8512 strv_free(arg_properties
);
8514 strv_free(arg_wall
);
8517 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8518 return r
< 0 ? EXIT_FAILURE
: r
;