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 "formats-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_no_block
= false;
122 static bool arg_no_legend
= false;
123 static bool arg_no_pager
= false;
124 static bool arg_no_wtmp
= false;
125 static bool arg_no_sync
= false;
126 static bool arg_no_wall
= false;
127 static bool arg_no_reload
= false;
128 static bool arg_value
= false;
129 static bool arg_show_types
= false;
130 static bool arg_ignore_inhibitors
= false;
131 static bool arg_dry
= false;
132 static bool arg_quiet
= false;
133 static bool arg_full
= false;
134 static bool arg_recursive
= false;
135 static int arg_force
= 0;
136 static bool arg_ask_password
= false;
137 static bool arg_runtime
= false;
138 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
139 static char **arg_wall
= NULL
;
140 static const char *arg_kill_who
= NULL
;
141 static int arg_signal
= SIGTERM
;
142 static char *arg_root
= NULL
;
143 static usec_t arg_when
= 0;
165 ACTION_CANCEL_SHUTDOWN
,
167 } arg_action
= ACTION_SYSTEMCTL
;
168 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
169 static const char *arg_host
= NULL
;
170 static unsigned arg_lines
= 10;
171 static OutputMode arg_output
= OUTPUT_SHORT
;
172 static bool arg_plain
= false;
173 static bool arg_firmware_setup
= false;
174 static bool arg_now
= false;
176 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
177 static int trivial_method(int argc
, char *argv
[], void *userdata
);
178 static int halt_now(enum action a
);
179 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
);
181 static bool original_stdout_is_tty
;
183 typedef enum BusFocus
{
184 BUS_FULL
, /* The full bus indicated via --system or --user */
185 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
189 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
191 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
194 assert(focus
< _BUS_FOCUS_MAX
);
197 /* We only go directly to the manager, if we are using a local transport */
198 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
201 if (!busses
[focus
]) {
204 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
206 if (focus
== BUS_MANAGER
)
207 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
209 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
211 return log_error_errno(r
, "Failed to connect to bus: %m");
213 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
216 *ret
= busses
[focus
];
220 static void release_busses(void) {
223 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
224 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
227 static void ask_password_agent_open_if_enabled(void) {
229 /* Open the password agent as a child process if necessary */
231 if (!arg_ask_password
)
234 if (arg_scope
!= UNIT_FILE_SYSTEM
)
237 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
240 ask_password_agent_open();
243 static void polkit_agent_open_if_enabled(void) {
245 /* Open the polkit agent as a child process if necessary */
247 if (!arg_ask_password
)
250 if (arg_scope
!= UNIT_FILE_SYSTEM
)
253 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
259 static OutputFlags
get_output_flags(void) {
261 arg_all
* OUTPUT_SHOW_ALL
|
262 arg_full
* OUTPUT_FULL_WIDTH
|
263 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
264 colors_enabled() * OUTPUT_COLOR
|
265 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
268 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
271 if (!sd_bus_error_is_set(error
))
274 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
275 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
276 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
277 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
278 return EXIT_NOPERMISSION
;
280 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
281 return EXIT_NOTINSTALLED
;
283 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
284 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
285 return EXIT_NOTIMPLEMENTED
;
287 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
288 return EXIT_NOTCONFIGURED
;
296 static bool install_client_side(void) {
298 /* Decides when to execute enable/disable/... operations
299 * client-side rather than server-side. */
301 if (running_in_chroot() > 0)
304 if (sd_booted() <= 0)
307 if (!isempty(arg_root
))
310 if (arg_scope
== UNIT_FILE_GLOBAL
)
313 /* Unsupported environment variable, mostly for debugging purposes */
314 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
320 static int compare_unit_info(const void *a
, const void *b
) {
321 const UnitInfo
*u
= a
, *v
= b
;
325 /* First, order by machine */
326 if (!u
->machine
&& v
->machine
)
328 if (u
->machine
&& !v
->machine
)
330 if (u
->machine
&& v
->machine
) {
331 r
= strcasecmp(u
->machine
, v
->machine
);
336 /* Second, order by unit type */
337 d1
= strrchr(u
->id
, '.');
338 d2
= strrchr(v
->id
, '.');
340 r
= strcasecmp(d1
, d2
);
345 /* Third, order by name */
346 return strcasecmp(u
->id
, v
->id
);
349 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
352 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
358 dot
= strrchr(u
->id
, '.');
362 if (!strv_find(arg_types
, dot
+1))
369 /* Note that '--all' is not purely a state filter, but also a
370 * filter that hides units that "follow" other units (which is
371 * used for device units that appear under different names). */
372 if (!isempty(u
->following
))
375 if (!strv_isempty(arg_states
))
378 /* By default show all units except the ones in inactive
379 * state and with no pending job */
383 if (streq(u
->active_state
, "inactive"))
389 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
390 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
392 unsigned n_shown
= 0;
395 max_id_len
= strlen("UNIT");
396 load_len
= strlen("LOAD");
397 active_len
= strlen("ACTIVE");
398 sub_len
= strlen("SUB");
399 job_len
= strlen("JOB");
402 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
403 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
404 load_len
= MAX(load_len
, strlen(u
->load_state
));
405 active_len
= MAX(active_len
, strlen(u
->active_state
));
406 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
408 if (u
->job_id
!= 0) {
409 job_len
= MAX(job_len
, strlen(u
->job_type
));
413 if (!arg_no_legend
&&
414 (streq(u
->active_state
, "failed") ||
415 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
419 if (!arg_full
&& original_stdout_is_tty
) {
422 id_len
= MIN(max_id_len
, 25u);
423 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
426 basic_len
+= job_len
+ 1;
428 if (basic_len
< (unsigned) columns()) {
429 unsigned extra_len
, incr
;
430 extra_len
= columns() - basic_len
;
432 /* Either UNIT already got 25, or is fully satisfied.
433 * Grant up to 25 to DESC now. */
434 incr
= MIN(extra_len
, 25u);
438 /* split the remaining space between UNIT and DESC,
439 * but do not give UNIT more than it needs. */
441 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
443 desc_len
+= extra_len
- incr
;
449 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
450 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
451 const char *on_loaded
= "", *off_loaded
= "";
452 const char *on_active
= "", *off_active
= "";
453 const char *on_circle
= "", *off_circle
= "";
457 if (!n_shown
&& !arg_no_legend
) {
462 printf("%-*s %-*s %-*s %-*s ",
465 active_len
, "ACTIVE",
469 printf("%-*s ", job_len
, "JOB");
471 if (!arg_full
&& arg_no_pager
)
472 printf("%.*s\n", desc_len
, "DESCRIPTION");
474 printf("%s\n", "DESCRIPTION");
479 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
480 on_loaded
= ansi_highlight_red();
481 on_circle
= ansi_highlight_yellow();
482 off_loaded
= off_circle
= ansi_normal();
484 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
485 on_circle
= on_active
= ansi_highlight_red();
486 off_circle
= off_active
= ansi_normal();
491 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
500 e
= ellipsize(id
, id_len
, 33);
508 printf("%s%s%s ", on_circle
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_circle
);
510 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
511 on_active
, id_len
, id
, off_active
,
512 on_loaded
, load_len
, u
->load_state
, off_loaded
,
513 on_active
, active_len
, u
->active_state
,
514 sub_len
, u
->sub_state
, off_active
,
515 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
518 printf("%.*s\n", desc_len
, u
->description
);
520 printf("%s\n", u
->description
);
523 if (!arg_no_legend
) {
524 const char *on
, *off
;
528 "LOAD = Reflects whether the unit definition was properly loaded.\n"
529 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
530 "SUB = The low-level unit activation state, values depend on unit type.");
531 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
532 on
= ansi_highlight();
535 on
= ansi_highlight_red();
540 printf("%s%u loaded units listed.%s\n"
541 "To show all installed unit files use 'systemctl list-unit-files'.\n",
544 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
545 "To show all installed unit files use 'systemctl list-unit-files'.\n",
552 static int get_unit_list(
556 UnitInfo
**unit_infos
,
558 sd_bus_message
**_reply
) {
560 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
561 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
562 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
566 bool fallback
= false;
572 r
= sd_bus_message_new_method_call(
575 "org.freedesktop.systemd1",
576 "/org/freedesktop/systemd1",
577 "org.freedesktop.systemd1.Manager",
578 "ListUnitsByPatterns");
580 return bus_log_create_error(r
);
582 r
= sd_bus_message_append_strv(m
, arg_states
);
584 return bus_log_create_error(r
);
586 r
= sd_bus_message_append_strv(m
, patterns
);
588 return bus_log_create_error(r
);
590 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
591 if (r
< 0 && (sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
) ||
592 sd_bus_error_has_name(&error
, SD_BUS_ERROR_ACCESS_DENIED
))) {
593 /* Fallback to legacy ListUnitsFiltered method */
595 log_debug_errno(r
, "Failed to list units: %s Falling back to ListUnitsFiltered method.", bus_error_message(&error
, r
));
596 m
= sd_bus_message_unref(m
);
597 sd_bus_error_free(&error
);
599 r
= sd_bus_message_new_method_call(
602 "org.freedesktop.systemd1",
603 "/org/freedesktop/systemd1",
604 "org.freedesktop.systemd1.Manager",
605 "ListUnitsFiltered");
607 return bus_log_create_error(r
);
609 r
= sd_bus_message_append_strv(m
, arg_states
);
611 return bus_log_create_error(r
);
613 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
616 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
618 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
620 return bus_log_parse_error(r
);
622 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
625 if (!output_show_unit(&u
, fallback
? patterns
: NULL
))
628 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
631 (*unit_infos
)[c
++] = u
;
634 return bus_log_parse_error(r
);
636 r
= sd_bus_message_exit_container(reply
);
638 return bus_log_parse_error(r
);
646 static void message_set_freep(Set
**set
) {
649 while ((m
= set_steal_first(*set
)))
650 sd_bus_message_unref(m
);
655 static int get_unit_list_recursive(
658 UnitInfo
**_unit_infos
,
662 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
663 _cleanup_(message_set_freep
) Set
*replies
;
664 sd_bus_message
*reply
;
672 replies
= set_new(NULL
);
676 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
680 r
= set_put(replies
, reply
);
682 sd_bus_message_unref(reply
);
687 _cleanup_strv_free_
char **machines
= NULL
;
690 r
= sd_get_machine_names(&machines
);
692 return log_error_errno(r
, "Failed to get machine names: %m");
694 STRV_FOREACH(i
, machines
) {
695 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
698 r
= sd_bus_open_system_machine(&container
, *i
);
700 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
704 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
710 r
= set_put(replies
, reply
);
712 sd_bus_message_unref(reply
);
717 *_machines
= machines
;
722 *_unit_infos
= unit_infos
;
731 static int list_units(int argc
, char *argv
[], void *userdata
) {
732 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
733 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
734 _cleanup_strv_free_
char **machines
= NULL
;
738 r
= acquire_bus(BUS_MANAGER
, &bus
);
742 pager_open(arg_no_pager
, false);
744 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
748 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
749 return output_units_list(unit_infos
, r
);
752 static int get_triggered_units(
757 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
764 r
= sd_bus_get_property_strv(
766 "org.freedesktop.systemd1",
768 "org.freedesktop.systemd1.Unit",
773 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
778 static int get_listening(
780 const char* unit_path
,
783 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
784 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
785 const char *type
, *path
;
788 r
= sd_bus_get_property(
790 "org.freedesktop.systemd1",
792 "org.freedesktop.systemd1.Socket",
798 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
800 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
802 return bus_log_parse_error(r
);
804 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
806 r
= strv_extend(listening
, type
);
810 r
= strv_extend(listening
, path
);
817 return bus_log_parse_error(r
);
819 r
= sd_bus_message_exit_container(reply
);
821 return bus_log_parse_error(r
);
833 /* Note: triggered is a list here, although it almost certainly
834 * will always be one unit. Nevertheless, dbus API allows for multiple
835 * values, so let's follow that. */
838 /* The strv above is shared. free is set only in the first one. */
842 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
848 if (!a
->machine
&& b
->machine
)
850 if (a
->machine
&& !b
->machine
)
852 if (a
->machine
&& b
->machine
) {
853 o
= strcasecmp(a
->machine
, b
->machine
);
858 o
= strcmp(a
->path
, b
->path
);
860 o
= strcmp(a
->type
, b
->type
);
865 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
866 struct socket_info
*s
;
867 unsigned pathlen
= strlen("LISTEN"),
868 typelen
= strlen("TYPE") * arg_show_types
,
869 socklen
= strlen("UNIT"),
870 servlen
= strlen("ACTIVATES");
871 const char *on
, *off
;
873 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
877 socklen
= MAX(socklen
, strlen(s
->id
));
879 typelen
= MAX(typelen
, strlen(s
->type
));
880 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
882 STRV_FOREACH(a
, s
->triggered
)
883 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
884 servlen
= MAX(servlen
, tmp
);
889 printf("%-*s %-*.*s%-*s %s\n",
891 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
895 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
896 _cleanup_free_
char *j
= NULL
;
901 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
909 printf("%-*s %-*s %-*s",
910 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
913 pathlen
, path
, socklen
, s
->id
);
914 STRV_FOREACH(a
, s
->triggered
)
916 a
== s
->triggered
? "" : ",", *a
);
920 on
= ansi_highlight();
925 on
= ansi_highlight_red();
929 if (!arg_no_legend
) {
930 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
932 printf("Pass --all to see loaded but inactive sockets, too.\n");
938 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
939 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
940 _cleanup_strv_free_
char **machines
= NULL
;
941 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
942 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
944 struct socket_info
*s
;
950 r
= acquire_bus(BUS_MANAGER
, &bus
);
954 pager_open(arg_no_pager
, false);
956 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
960 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
961 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
964 if (!endswith(u
->id
, ".socket"))
967 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
971 c
= get_listening(bus
, u
->unit_path
, &listening
);
977 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
982 for (i
= 0; i
< c
; i
++)
983 socket_infos
[cs
+ i
] = (struct socket_info
) {
984 .machine
= u
->machine
,
986 .type
= listening
[i
*2],
987 .path
= listening
[i
*2 + 1],
988 .triggered
= triggered
,
989 .own_triggered
= i
==0,
992 /* from this point on we will cleanup those socket_infos */
995 listening
= triggered
= NULL
; /* avoid cleanup */
998 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
999 (__compar_fn_t
) socket_info_compare
);
1001 output_sockets_list(socket_infos
, cs
);
1004 assert(cs
== 0 || socket_infos
);
1005 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
1008 if (s
->own_triggered
)
1009 strv_free(s
->triggered
);
1015 static int get_next_elapse(
1018 dual_timestamp
*next
) {
1020 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1028 r
= sd_bus_get_property_trivial(
1030 "org.freedesktop.systemd1",
1032 "org.freedesktop.systemd1.Timer",
1033 "NextElapseUSecMonotonic",
1038 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1040 r
= sd_bus_get_property_trivial(
1042 "org.freedesktop.systemd1",
1044 "org.freedesktop.systemd1.Timer",
1045 "NextElapseUSecRealtime",
1050 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1056 static int get_last_trigger(
1061 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1068 r
= sd_bus_get_property_trivial(
1070 "org.freedesktop.systemd1",
1072 "org.freedesktop.systemd1.Timer",
1078 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1084 const char* machine
;
1087 usec_t last_trigger
;
1091 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1097 if (!a
->machine
&& b
->machine
)
1099 if (a
->machine
&& !b
->machine
)
1101 if (a
->machine
&& b
->machine
) {
1102 o
= strcasecmp(a
->machine
, b
->machine
);
1107 if (a
->next_elapse
< b
->next_elapse
)
1109 if (a
->next_elapse
> b
->next_elapse
)
1112 return strcmp(a
->id
, b
->id
);
1115 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1116 struct timer_info
*t
;
1118 nextlen
= strlen("NEXT"),
1119 leftlen
= strlen("LEFT"),
1120 lastlen
= strlen("LAST"),
1121 passedlen
= strlen("PASSED"),
1122 unitlen
= strlen("UNIT"),
1123 activatelen
= strlen("ACTIVATES");
1125 const char *on
, *off
;
1127 assert(timer_infos
|| n
== 0);
1129 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1133 if (t
->next_elapse
> 0) {
1134 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1136 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1137 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1139 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1140 leftlen
= MAX(leftlen
, strlen(trel
));
1143 if (t
->last_trigger
> 0) {
1144 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1146 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1147 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1149 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1150 passedlen
= MAX(passedlen
, strlen(trel
));
1153 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1155 STRV_FOREACH(a
, t
->triggered
)
1156 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1158 activatelen
= MAX(activatelen
, ul
);
1163 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1167 passedlen
, "PASSED",
1171 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1172 _cleanup_free_
char *j
= NULL
;
1174 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1175 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1178 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1179 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1181 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1182 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1185 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1192 printf("%-*s %-*s %-*s %-*s %-*s",
1193 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1195 STRV_FOREACH(a
, t
->triggered
)
1197 a
== t
->triggered
? "" : ",", *a
);
1201 on
= ansi_highlight();
1202 off
= ansi_normal();
1206 on
= ansi_highlight_red();
1207 off
= ansi_normal();
1210 if (!arg_no_legend
) {
1211 printf("%s%u timers listed.%s\n", on
, n
, off
);
1213 printf("Pass --all to see loaded but inactive timers, too.\n");
1219 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1225 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1228 if (next
->monotonic
> nw
->monotonic
)
1229 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1231 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1233 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1234 next_elapse
= MIN(converted
, next
->realtime
);
1236 next_elapse
= converted
;
1239 next_elapse
= next
->realtime
;
1244 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1245 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1246 _cleanup_strv_free_
char **machines
= NULL
;
1247 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1248 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1249 struct timer_info
*t
;
1257 r
= acquire_bus(BUS_MANAGER
, &bus
);
1261 pager_open(arg_no_pager
, false);
1263 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1267 dual_timestamp_get(&nw
);
1269 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1270 _cleanup_strv_free_
char **triggered
= NULL
;
1271 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1274 if (!endswith(u
->id
, ".timer"))
1277 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1281 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1285 get_last_trigger(bus
, u
->unit_path
, &last
);
1287 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1292 m
= calc_next_elapse(&nw
, &next
);
1294 timer_infos
[c
++] = (struct timer_info
) {
1295 .machine
= u
->machine
,
1298 .last_trigger
= last
,
1299 .triggered
= triggered
,
1302 triggered
= NULL
; /* avoid cleanup */
1305 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1306 (__compar_fn_t
) timer_info_compare
);
1308 output_timers_list(timer_infos
, c
);
1311 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1312 strv_free(t
->triggered
);
1317 static int compare_unit_file_list(const void *a
, const void *b
) {
1318 const char *d1
, *d2
;
1319 const UnitFileList
*u
= a
, *v
= b
;
1321 d1
= strrchr(u
->path
, '.');
1322 d2
= strrchr(v
->path
, '.');
1327 r
= strcasecmp(d1
, d2
);
1332 return strcasecmp(basename(u
->path
), basename(v
->path
));
1335 static bool output_show_unit_file(const UnitFileList
*u
, char **states
, char **patterns
) {
1338 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1341 if (!strv_isempty(arg_types
)) {
1344 dot
= strrchr(u
->path
, '.');
1348 if (!strv_find(arg_types
, dot
+1))
1352 if (!strv_isempty(states
) &&
1353 !strv_find(states
, unit_file_state_to_string(u
->state
)))
1359 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1360 unsigned max_id_len
, id_cols
, state_cols
;
1361 const UnitFileList
*u
;
1363 max_id_len
= strlen("UNIT FILE");
1364 state_cols
= strlen("STATE");
1366 for (u
= units
; u
< units
+ c
; u
++) {
1367 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1368 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1372 unsigned basic_cols
;
1374 id_cols
= MIN(max_id_len
, 25u);
1375 basic_cols
= 1 + id_cols
+ state_cols
;
1376 if (basic_cols
< (unsigned) columns())
1377 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1379 id_cols
= max_id_len
;
1381 if (!arg_no_legend
&& c
> 0)
1382 printf("%-*s %-*s\n",
1383 id_cols
, "UNIT FILE",
1384 state_cols
, "STATE");
1386 for (u
= units
; u
< units
+ c
; u
++) {
1387 _cleanup_free_
char *e
= NULL
;
1388 const char *on
, *off
;
1391 if (IN_SET(u
->state
,
1393 UNIT_FILE_MASKED_RUNTIME
,
1396 on
= ansi_highlight_red();
1397 off
= ansi_normal();
1398 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1399 on
= ansi_highlight_green();
1400 off
= ansi_normal();
1404 id
= basename(u
->path
);
1406 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1408 printf("%-*s %s%-*s%s\n",
1409 id_cols
, e
? e
: id
,
1410 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1414 printf("\n%u unit files listed.\n", c
);
1417 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1418 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1419 _cleanup_free_ UnitFileList
*units
= NULL
;
1426 bool fallback
= false;
1428 if (install_client_side()) {
1434 h
= hashmap_new(&string_hash_ops
);
1438 r
= unit_file_get_list(arg_scope
, arg_root
, h
, arg_states
, strv_skip(argv
, 1));
1440 unit_file_list_free(h
);
1441 return log_error_errno(r
, "Failed to get unit file list: %m");
1444 n_units
= hashmap_size(h
);
1446 units
= new(UnitFileList
, n_units
?: 1); /* avoid malloc(0) */
1448 unit_file_list_free(h
);
1452 HASHMAP_FOREACH(u
, h
, i
) {
1453 if (!output_show_unit_file(u
, NULL
, NULL
))
1460 assert(c
<= n_units
);
1465 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1466 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1469 r
= acquire_bus(BUS_MANAGER
, &bus
);
1473 r
= sd_bus_message_new_method_call(
1476 "org.freedesktop.systemd1",
1477 "/org/freedesktop/systemd1",
1478 "org.freedesktop.systemd1.Manager",
1479 "ListUnitFilesByPatterns");
1481 return bus_log_create_error(r
);
1483 r
= sd_bus_message_append_strv(m
, arg_states
);
1485 return bus_log_create_error(r
);
1487 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
1489 return bus_log_create_error(r
);
1491 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1492 if (r
< 0 && sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
)) {
1493 /* Fallback to legacy ListUnitFiles method */
1495 log_debug_errno(r
, "Failed to list unit files: %s Falling back to ListUnitsFiles method.", bus_error_message(&error
, r
));
1496 m
= sd_bus_message_unref(m
);
1497 sd_bus_error_free(&error
);
1499 r
= sd_bus_message_new_method_call(
1502 "org.freedesktop.systemd1",
1503 "/org/freedesktop/systemd1",
1504 "org.freedesktop.systemd1.Manager",
1507 return bus_log_create_error(r
);
1509 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
1512 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1514 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1516 return bus_log_parse_error(r
);
1518 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1520 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1523 units
[c
] = (struct UnitFileList
) {
1525 unit_file_state_from_string(state
)
1528 if (output_show_unit_file(&units
[c
],
1529 fallback
? arg_states
: NULL
,
1530 fallback
? strv_skip(argv
, 1) : NULL
))
1535 return bus_log_parse_error(r
);
1537 r
= sd_bus_message_exit_container(reply
);
1539 return bus_log_parse_error(r
);
1542 pager_open(arg_no_pager
, false);
1544 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1545 output_unit_file_list(units
, c
);
1547 if (install_client_side())
1548 for (unit
= units
; unit
< units
+ c
; unit
++)
1554 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1555 _cleanup_free_
char *n
= NULL
;
1556 size_t max_len
= MAX(columns(),20u);
1562 for (i
= level
- 1; i
>= 0; i
--) {
1564 if (len
> max_len
- 3 && !arg_full
) {
1565 printf("%s...\n",max_len
% 2 ? "" : " ");
1568 printf("%s", special_glyph(branches
& (1 << i
) ? TREE_VERTICAL
: TREE_SPACE
));
1572 if (len
> max_len
- 3 && !arg_full
) {
1573 printf("%s...\n",max_len
% 2 ? "" : " ");
1577 printf("%s", special_glyph(last
? TREE_RIGHT
: TREE_BRANCH
));
1581 printf("%s\n", name
);
1585 n
= ellipsize(name
, max_len
-len
, 100);
1593 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1595 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1596 [DEPENDENCY_FORWARD
] = "Requires\0"
1601 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1606 [DEPENDENCY_AFTER
] = "After\0",
1607 [DEPENDENCY_BEFORE
] = "Before\0",
1610 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1611 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1612 _cleanup_strv_free_
char **ret
= NULL
;
1613 _cleanup_free_
char *path
= NULL
;
1619 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1621 path
= unit_dbus_path_from_name(name
);
1625 r
= sd_bus_call_method(
1627 "org.freedesktop.systemd1",
1629 "org.freedesktop.DBus.Properties",
1633 "s", "org.freedesktop.systemd1.Unit");
1635 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1637 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1639 return bus_log_parse_error(r
);
1641 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1644 r
= sd_bus_message_read(reply
, "s", &prop
);
1646 return bus_log_parse_error(r
);
1648 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1649 r
= sd_bus_message_skip(reply
, "v");
1651 return bus_log_parse_error(r
);
1654 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1656 return bus_log_parse_error(r
);
1658 r
= bus_message_read_strv_extend(reply
, &ret
);
1660 return bus_log_parse_error(r
);
1662 r
= sd_bus_message_exit_container(reply
);
1664 return bus_log_parse_error(r
);
1667 r
= sd_bus_message_exit_container(reply
);
1669 return bus_log_parse_error(r
);
1673 return bus_log_parse_error(r
);
1675 r
= sd_bus_message_exit_container(reply
);
1677 return bus_log_parse_error(r
);
1685 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1686 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1688 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1690 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1693 return strcasecmp(*a
, *b
);
1696 static int list_dependencies_one(
1701 unsigned int branches
) {
1703 _cleanup_strv_free_
char **deps
= NULL
;
1711 r
= strv_extend(units
, name
);
1715 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1719 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1721 STRV_FOREACH(c
, deps
) {
1722 if (strv_contains(*units
, *c
)) {
1724 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1734 UnitActiveState active_state
= _UNIT_ACTIVE_STATE_INVALID
;
1737 (void) get_state_one_unit(bus
, *c
, &active_state
);
1739 switch (active_state
) {
1741 case UNIT_RELOADING
:
1742 case UNIT_ACTIVATING
:
1743 on
= ansi_highlight_green();
1747 case UNIT_DEACTIVATING
:
1752 on
= ansi_highlight_red();
1756 printf("%s%s%s ", on
, special_glyph(BLACK_CIRCLE
), ansi_normal());
1759 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1763 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1764 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1771 strv_remove(*units
, name
);
1776 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1777 _cleanup_strv_free_
char **units
= NULL
;
1778 _cleanup_free_
char *unit
= NULL
;
1784 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1786 return log_error_errno(r
, "Failed to mangle unit name: %m");
1790 u
= SPECIAL_DEFAULT_TARGET
;
1792 r
= acquire_bus(BUS_MANAGER
, &bus
);
1796 pager_open(arg_no_pager
, false);
1800 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1803 struct machine_info
{
1807 char *control_group
;
1808 uint32_t n_failed_units
;
1813 static const struct bus_properties_map machine_info_property_map
[] = {
1814 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1815 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1816 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1817 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1818 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1822 static void machine_info_clear(struct machine_info
*info
) {
1826 free(info
->control_group
);
1831 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1837 for (i
= 0; i
< n
; i
++)
1838 machine_info_clear(&machine_infos
[i
]);
1840 free(machine_infos
);
1843 static int compare_machine_info(const void *a
, const void *b
) {
1844 const struct machine_info
*u
= a
, *v
= b
;
1846 if (u
->is_host
!= v
->is_host
)
1847 return u
->is_host
> v
->is_host
? -1 : 1;
1849 return strcasecmp(u
->name
, v
->name
);
1852 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1853 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1859 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1866 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1873 static bool output_show_machine(const char *name
, char **patterns
) {
1874 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1877 static int get_machine_list(
1879 struct machine_info
**_machine_infos
,
1882 struct machine_info
*machine_infos
= NULL
;
1883 _cleanup_strv_free_
char **m
= NULL
;
1884 _cleanup_free_
char *hn
= NULL
;
1889 hn
= gethostname_malloc();
1893 if (output_show_machine(hn
, patterns
)) {
1894 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1897 machine_infos
[c
].is_host
= true;
1898 machine_infos
[c
].name
= hn
;
1901 get_machine_properties(bus
, &machine_infos
[c
]);
1905 r
= sd_get_machine_names(&m
);
1907 return log_error_errno(r
, "Failed to get machine list: %m");
1909 STRV_FOREACH(i
, m
) {
1910 _cleanup_free_
char *class = NULL
;
1912 if (!output_show_machine(*i
, patterns
))
1915 sd_machine_get_class(*i
, &class);
1916 if (!streq_ptr(class, "container"))
1919 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1920 free_machines_list(machine_infos
, c
);
1924 machine_infos
[c
].is_host
= false;
1925 machine_infos
[c
].name
= strdup(*i
);
1926 if (!machine_infos
[c
].name
) {
1927 free_machines_list(machine_infos
, c
);
1931 get_machine_properties(NULL
, &machine_infos
[c
]);
1935 *_machine_infos
= machine_infos
;
1939 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1940 struct machine_info
*m
;
1943 namelen
= sizeof("NAME") - 1,
1944 statelen
= sizeof("STATE") - 1,
1945 failedlen
= sizeof("FAILED") - 1,
1946 jobslen
= sizeof("JOBS") - 1;
1948 assert(machine_infos
|| n
== 0);
1950 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1951 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1952 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1953 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1954 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1956 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1960 if (!arg_no_legend
) {
1964 printf("%-*s %-*s %-*s %-*s\n",
1967 failedlen
, "FAILED",
1971 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1972 const char *on_state
= "", *off_state
= "";
1973 const char *on_failed
= "", *off_failed
= "";
1974 bool circle
= false;
1976 if (streq_ptr(m
->state
, "degraded")) {
1977 on_state
= ansi_highlight_red();
1978 off_state
= ansi_normal();
1980 } else if (!streq_ptr(m
->state
, "running")) {
1981 on_state
= ansi_highlight_yellow();
1982 off_state
= ansi_normal();
1986 if (m
->n_failed_units
> 0) {
1987 on_failed
= ansi_highlight_red();
1988 off_failed
= ansi_normal();
1990 on_failed
= off_failed
= "";
1993 printf("%s%s%s ", on_state
, circle
? special_glyph(BLACK_CIRCLE
) : " ", off_state
);
1996 printf("%-*s (host) %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
1997 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1998 on_state
, statelen
, strna(m
->state
), off_state
,
1999 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2000 jobslen
, m
->n_jobs
);
2002 printf("%-*s %s%-*s%s %s%*" PRIu32
"%s %*" PRIu32
"\n",
2003 namelen
, strna(m
->name
),
2004 on_state
, statelen
, strna(m
->state
), off_state
,
2005 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
2006 jobslen
, m
->n_jobs
);
2010 printf("\n%u machines listed.\n", n
);
2013 static int list_machines(int argc
, char *argv
[], void *userdata
) {
2014 struct machine_info
*machine_infos
= NULL
;
2018 if (geteuid() != 0) {
2019 log_error("Must be root.");
2023 r
= acquire_bus(BUS_MANAGER
, &bus
);
2027 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
2031 pager_open(arg_no_pager
, false);
2033 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
2034 output_machines_list(machine_infos
, r
);
2035 free_machines_list(machine_infos
, r
);
2040 static int get_default(int argc
, char *argv
[], void *userdata
) {
2041 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2042 _cleanup_free_
char *_path
= NULL
;
2046 if (install_client_side()) {
2047 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
2049 return log_error_errno(r
, "Failed to get default target: %m");
2054 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2057 r
= acquire_bus(BUS_MANAGER
, &bus
);
2061 r
= sd_bus_call_method(
2063 "org.freedesktop.systemd1",
2064 "/org/freedesktop/systemd1",
2065 "org.freedesktop.systemd1.Manager",
2071 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
2073 r
= sd_bus_message_read(reply
, "s", &path
);
2075 return bus_log_parse_error(r
);
2079 printf("%s\n", path
);
2084 static int set_default(int argc
, char *argv
[], void *userdata
) {
2085 _cleanup_free_
char *unit
= NULL
;
2086 UnitFileChange
*changes
= NULL
;
2087 unsigned n_changes
= 0;
2093 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
2095 return log_error_errno(r
, "Failed to mangle unit name: %m");
2097 if (install_client_side()) {
2098 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2099 unit_file_dump_changes(r
, "set default", changes
, n_changes
, arg_quiet
);
2104 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2105 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2108 polkit_agent_open_if_enabled();
2110 r
= acquire_bus(BUS_MANAGER
, &bus
);
2114 r
= sd_bus_call_method(
2116 "org.freedesktop.systemd1",
2117 "/org/freedesktop/systemd1",
2118 "org.freedesktop.systemd1.Manager",
2124 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2126 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
2130 /* Try to reload if enabled */
2132 r
= daemon_reload(argc
, argv
, userdata
);
2138 unit_file_changes_free(changes
, n_changes
);
2145 const char *name
, *type
, *state
;
2148 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2149 unsigned id_len
, unit_len
, type_len
, state_len
;
2150 const struct job_info
*j
;
2151 const char *on
, *off
;
2152 bool shorten
= false;
2154 assert(n
== 0 || jobs
);
2157 if (!arg_no_legend
) {
2158 on
= ansi_highlight_green();
2159 off
= ansi_normal();
2161 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2166 pager_open(arg_no_pager
, false);
2168 id_len
= strlen("JOB");
2169 unit_len
= strlen("UNIT");
2170 type_len
= strlen("TYPE");
2171 state_len
= strlen("STATE");
2173 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2174 uint32_t id
= j
->id
;
2175 assert(j
->name
&& j
->type
&& j
->state
);
2177 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2178 unit_len
= MAX(unit_len
, strlen(j
->name
));
2179 type_len
= MAX(type_len
, strlen(j
->type
));
2180 state_len
= MAX(state_len
, strlen(j
->state
));
2183 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2184 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2189 printf("%*s %-*s %-*s %-*s\n",
2193 state_len
, "STATE");
2195 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2196 _cleanup_free_
char *e
= NULL
;
2198 if (streq(j
->state
, "running")) {
2199 on
= ansi_highlight();
2200 off
= ansi_normal();
2204 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2205 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2207 on
, unit_len
, e
? e
: j
->name
, off
,
2209 on
, state_len
, j
->state
, off
);
2212 if (!arg_no_legend
) {
2213 on
= ansi_highlight();
2214 off
= ansi_normal();
2216 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2220 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2221 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2224 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2225 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2226 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2227 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2228 _cleanup_free_
struct job_info
*jobs
= NULL
;
2234 bool skipped
= false;
2236 r
= acquire_bus(BUS_MANAGER
, &bus
);
2240 r
= sd_bus_call_method(
2242 "org.freedesktop.systemd1",
2243 "/org/freedesktop/systemd1",
2244 "org.freedesktop.systemd1.Manager",
2250 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2252 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2254 return bus_log_parse_error(r
);
2256 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2257 struct job_info job
= { id
, name
, type
, state
};
2259 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2264 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2270 return bus_log_parse_error(r
);
2272 r
= sd_bus_message_exit_container(reply
);
2274 return bus_log_parse_error(r
);
2276 pager_open(arg_no_pager
, false);
2278 output_jobs_list(jobs
, c
, skipped
);
2282 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2288 return trivial_method(argc
, argv
, userdata
);
2290 r
= acquire_bus(BUS_MANAGER
, &bus
);
2294 polkit_agent_open_if_enabled();
2296 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2297 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2301 q
= safe_atou32(*name
, &id
);
2303 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2305 q
= sd_bus_call_method(
2307 "org.freedesktop.systemd1",
2308 "/org/freedesktop/systemd1",
2309 "org.freedesktop.systemd1.Manager",
2315 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2324 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2325 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2329 /* We ignore all errors here, since this is used to show a
2332 /* We don't use unit_dbus_path_from_name() directly since we
2333 * don't want to load the unit if it isn't loaded. */
2335 r
= sd_bus_call_method(
2337 "org.freedesktop.systemd1",
2338 "/org/freedesktop/systemd1",
2339 "org.freedesktop.systemd1.Manager",
2347 r
= sd_bus_message_read(reply
, "o", &path
);
2351 r
= sd_bus_get_property_trivial(
2353 "org.freedesktop.systemd1",
2355 "org.freedesktop.systemd1.Unit",
2365 static void warn_unit_file_changed(const char *name
) {
2368 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2369 ansi_highlight_red(),
2372 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2375 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2382 STRV_FOREACH(p
, lp
->search_path
) {
2383 _cleanup_free_
char *path
;
2385 path
= path_join(arg_root
, *p
, unit_name
);
2389 if (access(path
, F_OK
) == 0) {
2399 static int unit_find_paths(
2401 const char *unit_name
,
2403 char **fragment_path
,
2404 char ***dropin_paths
) {
2406 _cleanup_free_
char *path
= NULL
;
2407 _cleanup_strv_free_
char **dropins
= NULL
;
2411 * Finds where the unit is defined on disk. Returns 0 if the unit
2412 * is not found. Returns 1 if it is found, and sets
2413 * - the path to the unit in *path, if it exists on disk,
2414 * - and a strv of existing drop-ins in *dropins,
2415 * if the arg is not NULL and any dropins were found.
2419 assert(fragment_path
);
2422 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2423 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2424 _cleanup_free_
char *unit
= NULL
;
2426 unit
= unit_dbus_path_from_name(unit_name
);
2430 r
= sd_bus_get_property_string(
2432 "org.freedesktop.systemd1",
2434 "org.freedesktop.systemd1.Unit",
2439 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2442 r
= sd_bus_get_property_strv(
2444 "org.freedesktop.systemd1",
2446 "org.freedesktop.systemd1.Unit",
2451 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2454 _cleanup_set_free_ Set
*names
;
2456 names
= set_new(NULL
);
2460 r
= set_put(names
, unit_name
);
2462 return log_error_errno(r
, "Failed to add unit name: %m");
2464 r
= unit_file_find_path(lp
, unit_name
, &path
);
2469 _cleanup_free_
char *template = NULL
;
2471 r
= unit_name_template(unit_name
, &template);
2472 if (r
< 0 && r
!= -EINVAL
)
2473 return log_error_errno(r
, "Failed to determine template name: %m");
2475 r
= unit_file_find_path(lp
, template, &path
);
2482 r
= unit_file_find_dropin_paths(lp
->search_path
, NULL
, names
, &dropins
);
2490 if (!isempty(path
)) {
2491 *fragment_path
= path
;
2496 if (dropin_paths
&& !strv_isempty(dropins
)) {
2497 *dropin_paths
= dropins
;
2502 if (r
== 0 && !arg_force
)
2503 log_error("No files found for %s.", unit_name
);
2508 static int get_state_one_unit(sd_bus
*bus
, const char *name
, UnitActiveState
*active_state
) {
2509 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2510 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2511 _cleanup_free_
char *buf
= NULL
;
2512 UnitActiveState state
;
2517 assert(active_state
);
2519 /* We don't use unit_dbus_path_from_name() directly since we don't want to load the unit unnecessarily, if it
2521 r
= sd_bus_call_method(
2523 "org.freedesktop.systemd1",
2524 "/org/freedesktop/systemd1",
2525 "org.freedesktop.systemd1.Manager",
2531 if (!sd_bus_error_has_name(&error
, BUS_ERROR_NO_SUCH_UNIT
))
2532 return log_error_errno(r
, "Failed to retrieve unit: %s", bus_error_message(&error
, r
));
2534 /* The unit is currently not loaded, hence say it's "inactive", since all units that aren't loaded are
2535 * considered inactive. */
2536 state
= UNIT_INACTIVE
;
2539 r
= sd_bus_message_read(reply
, "o", &path
);
2541 return bus_log_parse_error(r
);
2543 r
= sd_bus_get_property_string(
2545 "org.freedesktop.systemd1",
2547 "org.freedesktop.systemd1.Unit",
2552 return log_error_errno(r
, "Failed to retrieve unit state: %s", bus_error_message(&error
, r
));
2554 state
= unit_active_state_from_string(buf
);
2555 if (state
== _UNIT_ACTIVE_STATE_INVALID
) {
2556 log_error("Invalid unit state '%s' for: %s", buf
, name
);
2561 *active_state
= state
;
2565 static int check_triggering_units(
2569 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2570 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *load_state
= NULL
;
2571 _cleanup_strv_free_
char **triggered_by
= NULL
;
2572 bool print_warning_label
= true;
2573 UnitActiveState active_state
;
2577 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2579 return log_error_errno(r
, "Failed to mangle unit name: %m");
2581 path
= unit_dbus_path_from_name(n
);
2585 r
= sd_bus_get_property_string(
2587 "org.freedesktop.systemd1",
2589 "org.freedesktop.systemd1.Unit",
2594 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2596 if (streq(load_state
, "masked"))
2599 r
= sd_bus_get_property_strv(
2601 "org.freedesktop.systemd1",
2603 "org.freedesktop.systemd1.Unit",
2608 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2610 STRV_FOREACH(i
, triggered_by
) {
2611 r
= get_state_one_unit(bus
, *i
, &active_state
);
2615 if (!IN_SET(active_state
, UNIT_ACTIVE
, UNIT_RELOADING
))
2618 if (print_warning_label
) {
2619 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2620 print_warning_label
= false;
2623 log_warning(" %s", *i
);
2629 static const struct {
2632 } unit_actions
[] = {
2633 { "start", "StartUnit" },
2634 { "stop", "StopUnit" },
2635 { "condstop", "StopUnit" },
2636 { "reload", "ReloadUnit" },
2637 { "restart", "RestartUnit" },
2638 { "try-restart", "TryRestartUnit" },
2639 { "condrestart", "TryRestartUnit" },
2640 { "reload-or-restart", "ReloadOrRestartUnit" },
2641 { "try-reload-or-restart", "ReloadOrTryRestartUnit" },
2642 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2643 { "condreload", "ReloadOrTryRestartUnit" },
2644 { "force-reload", "ReloadOrTryRestartUnit" }
2647 static const char *verb_to_method(const char *verb
) {
2650 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2651 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2652 return unit_actions
[i
].method
;
2657 static const char *method_to_verb(const char *method
) {
2660 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2661 if (streq_ptr(unit_actions
[i
].method
, method
))
2662 return unit_actions
[i
].verb
;
2667 static int start_unit_one(
2672 sd_bus_error
*error
,
2673 BusWaitForJobs
*w
) {
2675 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2684 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2686 r
= sd_bus_call_method(
2688 "org.freedesktop.systemd1",
2689 "/org/freedesktop/systemd1",
2690 "org.freedesktop.systemd1.Manager",
2698 /* There's always a fallback possible for legacy actions. */
2699 if (arg_action
!= ACTION_SYSTEMCTL
)
2702 verb
= method_to_verb(method
);
2704 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2706 if (!sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
) &&
2707 !sd_bus_error_has_name(error
, BUS_ERROR_UNIT_MASKED
))
2708 log_error("See %s logs and 'systemctl%s status %s' for details.",
2709 arg_scope
== UNIT_FILE_SYSTEM
? "system" : "user",
2710 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user",
2716 r
= sd_bus_message_read(reply
, "o", &path
);
2718 return bus_log_parse_error(r
);
2720 if (need_daemon_reload(bus
, name
) > 0)
2721 warn_unit_file_changed(name
);
2724 log_debug("Adding %s to the set", path
);
2725 r
= bus_wait_for_jobs_add(w
, path
);
2733 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2734 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2741 STRV_FOREACH(name
, names
) {
2745 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2747 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2749 return log_error_errno(r
, "Failed to mangle name: %m");
2751 if (string_is_glob(t
))
2752 r
= strv_consume(&globs
, t
);
2754 r
= strv_consume(&mangled
, t
);
2759 /* Query the manager only if any of the names are a glob, since
2760 * this is fairly expensive */
2761 if (!strv_isempty(globs
)) {
2762 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2763 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2764 size_t allocated
, n
;
2766 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2770 n
= strv_length(mangled
);
2773 for (i
= 0; i
< r
; i
++) {
2774 if (!GREEDY_REALLOC(mangled
, allocated
, n
+2))
2777 mangled
[n
] = strdup(unit_infos
[i
].id
);
2781 mangled
[++n
] = NULL
;
2786 mangled
= NULL
; /* do not free */
2791 static const struct {
2795 } action_table
[_ACTION_MAX
] = {
2796 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2797 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2798 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2799 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2800 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2801 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2802 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2803 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2804 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2805 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2806 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2807 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2808 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2809 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2810 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2813 static enum action
verb_to_action(const char *verb
) {
2816 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2817 if (streq_ptr(action_table
[i
].verb
, verb
))
2820 return _ACTION_INVALID
;
2823 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2824 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2825 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2826 _cleanup_strv_free_
char **names
= NULL
;
2831 r
= acquire_bus(BUS_MANAGER
, &bus
);
2835 ask_password_agent_open_if_enabled();
2836 polkit_agent_open_if_enabled();
2838 if (arg_action
== ACTION_SYSTEMCTL
) {
2841 method
= verb_to_method(argv
[0]);
2842 action
= verb_to_action(argv
[0]);
2844 if (streq(argv
[0], "isolate")) {
2848 mode
= action_table
[action
].mode
?: arg_job_mode
;
2850 one_name
= action_table
[action
].target
;
2852 assert(arg_action
< ELEMENTSOF(action_table
));
2853 assert(action_table
[arg_action
].target
);
2855 method
= "StartUnit";
2857 mode
= action_table
[arg_action
].mode
;
2858 one_name
= action_table
[arg_action
].target
;
2862 names
= strv_new(one_name
, NULL
);
2864 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2866 return log_error_errno(r
, "Failed to expand names: %m");
2869 if (!arg_no_block
) {
2870 r
= bus_wait_for_jobs_new(bus
, &w
);
2872 return log_error_errno(r
, "Could not watch jobs: %m");
2875 STRV_FOREACH(name
, names
) {
2876 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2879 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2880 if (r
>= 0 && q
< 0)
2881 r
= translate_bus_error_to_exit_status(q
, &error
);
2884 if (!arg_no_block
) {
2885 int q
, arg_count
= 0;
2886 const char* extra_args
[4] = {};
2888 if (arg_scope
!= UNIT_FILE_SYSTEM
)
2889 extra_args
[arg_count
++] = "--user";
2891 assert(IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_REMOTE
, BUS_TRANSPORT_MACHINE
));
2892 if (arg_transport
== BUS_TRANSPORT_REMOTE
) {
2893 extra_args
[arg_count
++] = "-H";
2894 extra_args
[arg_count
++] = arg_host
;
2895 } else if (arg_transport
== BUS_TRANSPORT_MACHINE
) {
2896 extra_args
[arg_count
++] = "-M";
2897 extra_args
[arg_count
++] = arg_host
;
2900 q
= bus_wait_for_jobs(w
, arg_quiet
, extra_args
);
2904 /* When stopping units, warn if they can still be triggered by
2905 * another active unit (socket, path, timer) */
2906 if (!arg_quiet
&& streq(method
, "StopUnit"))
2907 STRV_FOREACH(name
, names
)
2908 check_triggering_units(bus
, *name
);
2914 static int logind_set_wall_message(void) {
2916 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2918 _cleanup_free_
char *m
= NULL
;
2921 r
= acquire_bus(BUS_FULL
, &bus
);
2925 m
= strv_join(arg_wall
, " ");
2929 r
= sd_bus_call_method(
2931 "org.freedesktop.login1",
2932 "/org/freedesktop/login1",
2933 "org.freedesktop.login1.Manager",
2942 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2948 /* Ask systemd-logind, which might grant access to unprivileged users
2949 * through PolicyKit */
2950 static int logind_reboot(enum action a
) {
2952 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2953 const char *method
, *description
;
2957 r
= acquire_bus(BUS_FULL
, &bus
);
2965 description
= "reboot system";
2968 case ACTION_POWEROFF
:
2969 method
= "PowerOff";
2970 description
= "power off system";
2973 case ACTION_SUSPEND
:
2975 description
= "suspend system";
2978 case ACTION_HIBERNATE
:
2979 method
= "Hibernate";
2980 description
= "hibernate system";
2983 case ACTION_HYBRID_SLEEP
:
2984 method
= "HybridSleep";
2985 description
= "put system into hybrid sleep";
2992 polkit_agent_open_if_enabled();
2993 (void) logind_set_wall_message();
2995 r
= sd_bus_call_method(
2997 "org.freedesktop.login1",
2998 "/org/freedesktop/login1",
2999 "org.freedesktop.login1.Manager",
3003 "b", arg_ask_password
);
3005 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
3013 static int logind_check_inhibitors(enum action a
) {
3015 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
3016 _cleanup_strv_free_
char **sessions
= NULL
;
3017 const char *what
, *who
, *why
, *mode
;
3024 if (arg_ignore_inhibitors
|| arg_force
> 0)
3036 r
= acquire_bus(BUS_FULL
, &bus
);
3040 r
= sd_bus_call_method(
3042 "org.freedesktop.login1",
3043 "/org/freedesktop/login1",
3044 "org.freedesktop.login1.Manager",
3050 /* If logind is not around, then there are no inhibitors... */
3053 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
3055 return bus_log_parse_error(r
);
3057 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
3058 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
3059 _cleanup_strv_free_
char **sv
= NULL
;
3061 if (!streq(mode
, "block"))
3064 sv
= strv_split(what
, ":");
3068 if ((pid_t
) pid
< 0)
3069 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
3071 if (!strv_contains(sv
,
3076 ACTION_KEXEC
) ? "shutdown" : "sleep"))
3079 get_process_comm(pid
, &comm
);
3080 user
= uid_to_name(uid
);
3082 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
3083 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
3088 return bus_log_parse_error(r
);
3090 r
= sd_bus_message_exit_container(reply
);
3092 return bus_log_parse_error(r
);
3094 /* Check for current sessions */
3095 sd_get_sessions(&sessions
);
3096 STRV_FOREACH(s
, sessions
) {
3097 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
3099 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
3102 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3105 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3108 sd_session_get_tty(*s
, &tty
);
3109 sd_session_get_seat(*s
, &seat
);
3110 sd_session_get_service(*s
, &service
);
3111 user
= uid_to_name(uid
);
3113 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3120 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3121 action_table
[a
].verb
);
3129 static int logind_prepare_firmware_setup(void) {
3131 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3135 r
= acquire_bus(BUS_FULL
, &bus
);
3139 r
= sd_bus_call_method(
3141 "org.freedesktop.login1",
3142 "/org/freedesktop/login1",
3143 "org.freedesktop.login1.Manager",
3144 "SetRebootToFirmwareSetup",
3149 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3153 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3158 static int prepare_firmware_setup(void) {
3161 if (!arg_firmware_setup
)
3164 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3166 r
= efi_set_reboot_to_firmware(true);
3168 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3173 return logind_prepare_firmware_setup();
3176 static int set_exit_code(uint8_t code
) {
3177 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3181 r
= acquire_bus(BUS_MANAGER
, &bus
);
3185 r
= sd_bus_call_method(
3187 "org.freedesktop.systemd1",
3188 "/org/freedesktop/systemd1",
3189 "org.freedesktop.systemd1.Manager",
3195 return log_error_errno(r
, "Failed to set exit code: %s", bus_error_message(&error
, r
));
3200 static int start_special(int argc
, char *argv
[], void *userdata
) {
3206 a
= verb_to_action(argv
[0]);
3208 r
= logind_check_inhibitors(a
);
3212 if (arg_force
>= 2 && geteuid() != 0) {
3213 log_error("Must be root.");
3217 r
= prepare_firmware_setup();
3221 if (a
== ACTION_REBOOT
&& argc
> 1) {
3222 r
= update_reboot_parameter_and_warn(argv
[1]);
3226 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3229 /* If the exit code is not given on the command line,
3230 * don't reset it to zero: just keep it as it might
3231 * have been set previously. */
3233 r
= safe_atou8(argv
[1], &code
);
3235 return log_error_errno(r
, "Invalid exit code.");
3237 r
= set_exit_code(code
);
3242 if (arg_force
>= 2 &&
3249 if (arg_force
>= 1 &&
3256 return trivial_method(argc
, argv
, userdata
);
3258 /* First try logind, to allow authentication with polkit */
3264 ACTION_HYBRID_SLEEP
)) {
3265 r
= logind_reboot(a
);
3268 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3269 /* requested operation is not supported or already in progress */
3272 /* On all other errors, try low-level operation */
3275 return start_unit(argc
, argv
, userdata
);
3278 static int start_system_special(int argc
, char *argv
[], void *userdata
) {
3279 /* Like start_special above, but raises an error when running in user mode */
3281 if (arg_scope
!= UNIT_FILE_SYSTEM
) {
3282 log_error("Bad action for %s mode.",
3283 arg_scope
== UNIT_FILE_GLOBAL
? "--global" : "--user");
3287 return start_special(argc
, argv
, userdata
);
3290 static int check_unit_generic(int code
, const UnitActiveState good_states
[], int nb_states
, char **args
) {
3291 _cleanup_strv_free_
char **names
= NULL
;
3292 UnitActiveState active_state
;
3298 r
= acquire_bus(BUS_MANAGER
, &bus
);
3302 r
= expand_names(bus
, args
, NULL
, &names
);
3304 return log_error_errno(r
, "Failed to expand names: %m");
3306 STRV_FOREACH(name
, names
) {
3307 r
= get_state_one_unit(bus
, *name
, &active_state
);
3312 puts(unit_active_state_to_string(active_state
));
3314 for (i
= 0; i
< nb_states
; ++i
)
3315 if (good_states
[i
] == active_state
)
3319 /* use the given return code for the case that we won't find
3320 * any unit which matches the list */
3321 return found
? 0 : code
;
3324 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3325 const UnitActiveState states
[] = { UNIT_ACTIVE
, UNIT_RELOADING
};
3326 /* According to LSB: 3, "program is not running" */
3327 return check_unit_generic(EXIT_PROGRAM_NOT_RUNNING
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3330 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3331 const UnitActiveState states
[] = { UNIT_FAILED
};
3332 return check_unit_generic(EXIT_PROGRAM_DEAD_AND_PID_EXISTS
, states
, ELEMENTSOF(states
), strv_skip(argv
, 1));
3335 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3336 _cleanup_strv_free_
char **names
= NULL
;
3337 char *kill_who
= NULL
, **name
;
3341 r
= acquire_bus(BUS_MANAGER
, &bus
);
3345 polkit_agent_open_if_enabled();
3348 arg_kill_who
= "all";
3350 /* --fail was specified */
3351 if (streq(arg_job_mode
, "fail"))
3352 kill_who
= strjoina(arg_kill_who
, "-fail");
3354 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3356 return log_error_errno(r
, "Failed to expand names: %m");
3358 STRV_FOREACH(name
, names
) {
3359 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3361 q
= sd_bus_call_method(
3363 "org.freedesktop.systemd1",
3364 "/org/freedesktop/systemd1",
3365 "org.freedesktop.systemd1.Manager",
3369 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3371 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3380 typedef struct ExecStatusInfo
{
3388 usec_t start_timestamp
;
3389 usec_t exit_timestamp
;
3394 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3397 static void exec_status_info_free(ExecStatusInfo
*i
) {
3406 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3407 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3410 int32_t code
, status
;
3416 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3418 return bus_log_parse_error(r
);
3422 r
= sd_bus_message_read(m
, "s", &path
);
3424 return bus_log_parse_error(r
);
3426 i
->path
= strdup(path
);
3430 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3432 return bus_log_parse_error(r
);
3434 r
= sd_bus_message_read(m
,
3437 &start_timestamp
, &start_timestamp_monotonic
,
3438 &exit_timestamp
, &exit_timestamp_monotonic
,
3442 return bus_log_parse_error(r
);
3445 i
->start_timestamp
= (usec_t
) start_timestamp
;
3446 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3447 i
->pid
= (pid_t
) pid
;
3451 r
= sd_bus_message_exit_container(m
);
3453 return bus_log_parse_error(r
);
3458 typedef struct UnitStatusInfo
{
3460 const char *load_state
;
3461 const char *active_state
;
3462 const char *sub_state
;
3463 const char *unit_file_state
;
3464 const char *unit_file_preset
;
3466 const char *description
;
3467 const char *following
;
3469 char **documentation
;
3471 const char *fragment_path
;
3472 const char *source_path
;
3473 const char *control_group
;
3475 char **dropin_paths
;
3477 const char *load_error
;
3480 usec_t inactive_exit_timestamp
;
3481 usec_t inactive_exit_timestamp_monotonic
;
3482 usec_t active_enter_timestamp
;
3483 usec_t active_exit_timestamp
;
3484 usec_t inactive_enter_timestamp
;
3486 bool need_daemon_reload
;
3492 const char *status_text
;
3493 const char *pid_file
;
3497 usec_t start_timestamp
;
3498 usec_t exit_timestamp
;
3500 int exit_code
, exit_status
;
3502 usec_t condition_timestamp
;
3503 bool condition_result
;
3504 bool failed_condition_trigger
;
3505 bool failed_condition_negate
;
3506 const char *failed_condition
;
3507 const char *failed_condition_parameter
;
3509 usec_t assert_timestamp
;
3511 bool failed_assert_trigger
;
3512 bool failed_assert_negate
;
3513 const char *failed_assert
;
3514 const char *failed_assert_parameter
;
3517 unsigned n_accepted
;
3518 unsigned n_connections
;
3521 /* Pairs of type, path */
3525 const char *sysfs_path
;
3527 /* Mount, Automount */
3534 uint64_t memory_current
;
3535 uint64_t memory_low
;
3536 uint64_t memory_high
;
3537 uint64_t memory_max
;
3538 uint64_t memory_limit
;
3539 uint64_t cpu_usage_nsec
;
3540 uint64_t tasks_current
;
3543 LIST_HEAD(ExecStatusInfo
, exec
);
3546 static void print_status_info(
3552 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3554 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3555 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3562 /* This shows pretty information about a unit. See
3563 * print_property() for a low-level property printer */
3565 if (streq_ptr(i
->active_state
, "failed")) {
3566 active_on
= ansi_highlight_red();
3567 active_off
= ansi_normal();
3568 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3569 active_on
= ansi_highlight_green();
3570 active_off
= ansi_normal();
3572 active_on
= active_off
= "";
3574 printf("%s%s%s %s", active_on
, special_glyph(BLACK_CIRCLE
), active_off
, strna(i
->id
));
3576 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3577 printf(" - %s", i
->description
);
3582 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3584 if (streq_ptr(i
->load_state
, "error")) {
3585 on
= ansi_highlight_red();
3586 off
= ansi_normal();
3590 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3592 if (i
->load_error
!= 0)
3593 printf(" Loaded: %s%s%s (Reason: %s)\n",
3594 on
, strna(i
->load_state
), off
, i
->load_error
);
3595 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3596 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3597 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3598 else if (path
&& !isempty(i
->unit_file_state
))
3599 printf(" Loaded: %s%s%s (%s; %s)\n",
3600 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3602 printf(" Loaded: %s%s%s (%s)\n",
3603 on
, strna(i
->load_state
), off
, path
);
3605 printf(" Loaded: %s%s%s\n",
3606 on
, strna(i
->load_state
), off
);
3609 printf("Transient: yes\n");
3611 if (!strv_isempty(i
->dropin_paths
)) {
3612 _cleanup_free_
char *dir
= NULL
;
3616 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3617 if (! dir
|| last
) {
3618 printf(dir
? " " : " Drop-In: ");
3622 dir
= dirname_malloc(*dropin
);
3628 printf("%s\n %s", dir
,
3629 special_glyph(TREE_RIGHT
));
3632 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3634 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3638 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3640 printf(" Active: %s%s (%s)%s",
3641 active_on
, strna(i
->active_state
), ss
, active_off
);
3643 printf(" Active: %s%s%s",
3644 active_on
, strna(i
->active_state
), active_off
);
3646 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3647 printf(" (Result: %s)", i
->result
);
3649 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3650 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3651 (streq_ptr(i
->active_state
, "inactive") ||
3652 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3653 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3654 i
->active_exit_timestamp
;
3656 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3657 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3660 printf(" since %s; %s\n", s2
, s1
);
3662 printf(" since %s\n", s2
);
3666 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3667 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3668 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3670 printf("Condition: start %scondition failed%s at %s%s%s\n",
3671 ansi_highlight_yellow(), ansi_normal(),
3672 s2
, s1
? "; " : "", strempty(s1
));
3673 if (i
->failed_condition_trigger
)
3674 printf(" none of the trigger conditions were met\n");
3675 else if (i
->failed_condition
)
3676 printf(" %s=%s%s was not met\n",
3677 i
->failed_condition
,
3678 i
->failed_condition_negate
? "!" : "",
3679 i
->failed_condition_parameter
);
3682 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3683 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3684 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3686 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3687 ansi_highlight_red(), ansi_normal(),
3688 s2
, s1
? "; " : "", strempty(s1
));
3689 if (i
->failed_assert_trigger
)
3690 printf(" none of the trigger assertions were met\n");
3691 else if (i
->failed_assert
)
3692 printf(" %s=%s%s was not met\n",
3694 i
->failed_assert_negate
? "!" : "",
3695 i
->failed_assert_parameter
);
3699 printf(" Device: %s\n", i
->sysfs_path
);
3701 printf(" Where: %s\n", i
->where
);
3703 printf(" What: %s\n", i
->what
);
3705 STRV_FOREACH(t
, i
->documentation
)
3706 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3708 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3709 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3712 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3714 LIST_FOREACH(exec
, p
, i
->exec
) {
3715 _cleanup_free_
char *argv
= NULL
;
3718 /* Only show exited processes here */
3722 argv
= strv_join(p
->argv
, " ");
3723 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3725 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3727 on
= ansi_highlight_red();
3728 off
= ansi_normal();
3732 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3734 if (p
->code
== CLD_EXITED
) {
3737 printf("status=%i", p
->status
);
3739 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3744 printf("signal=%s", signal_to_string(p
->status
));
3746 printf(")%s\n", off
);
3748 if (i
->main_pid
== p
->pid
&&
3749 i
->start_timestamp
== p
->start_timestamp
&&
3750 i
->exit_timestamp
== p
->start_timestamp
)
3751 /* Let's not show this twice */
3754 if (p
->pid
== i
->control_pid
)
3758 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3759 if (i
->main_pid
> 0) {
3760 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3763 _cleanup_free_
char *comm
= NULL
;
3764 get_process_comm(i
->main_pid
, &comm
);
3766 printf(" (%s)", comm
);
3767 } else if (i
->exit_code
> 0) {
3768 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3770 if (i
->exit_code
== CLD_EXITED
) {
3773 printf("status=%i", i
->exit_status
);
3775 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3780 printf("signal=%s", signal_to_string(i
->exit_status
));
3784 if (i
->control_pid
> 0)
3788 if (i
->control_pid
> 0) {
3789 _cleanup_free_
char *c
= NULL
;
3791 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3793 get_process_comm(i
->control_pid
, &c
);
3802 printf(" Status: \"%s\"\n", i
->status_text
);
3803 if (i
->status_errno
> 0)
3804 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3806 if (i
->tasks_current
!= (uint64_t) -1) {
3807 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3809 if (i
->tasks_max
!= (uint64_t) -1)
3810 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3815 if (i
->memory_current
!= (uint64_t) -1) {
3816 char buf
[FORMAT_BYTES_MAX
];
3818 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3820 if (i
->memory_low
> 0 || i
->memory_high
!= CGROUP_LIMIT_MAX
|| i
->memory_max
!= CGROUP_LIMIT_MAX
||
3821 i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
3822 const char *prefix
= "";
3825 if (i
->memory_low
> 0) {
3826 printf("%slow: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_low
));
3829 if (i
->memory_high
!= CGROUP_LIMIT_MAX
) {
3830 printf("%shigh: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_high
));
3833 if (i
->memory_max
!= CGROUP_LIMIT_MAX
) {
3834 printf("%smax: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_max
));
3837 if (i
->memory_limit
!= CGROUP_LIMIT_MAX
) {
3838 printf("%slimit: %s", prefix
, format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3846 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3847 char buf
[FORMAT_TIMESPAN_MAX
];
3848 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3851 if (i
->control_group
) {
3852 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3853 static const char prefix
[] = " ";
3856 printf(" CGroup: %s\n", i
->control_group
);
3859 if (c
> sizeof(prefix
) - 1)
3860 c
-= sizeof(prefix
) - 1;
3864 r
= unit_show_processes(bus
, i
->id
, i
->control_group
, prefix
, c
, get_output_flags(), &error
);
3869 /* Fallback for older systemd versions where the GetUnitProcesses() call is not yet available */
3871 if (i
->main_pid
> 0)
3872 extra
[k
++] = i
->main_pid
;
3874 if (i
->control_pid
> 0)
3875 extra
[k
++] = i
->control_pid
;
3877 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, extra
, k
, get_output_flags());
3879 log_warning_errno(r
, "Failed to dump process list, ignoring: %s", bus_error_message(&error
, r
));
3882 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3883 show_journal_by_unit(
3888 i
->inactive_exit_timestamp_monotonic
,
3891 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3892 SD_JOURNAL_LOCAL_ONLY
,
3893 arg_scope
== UNIT_FILE_SYSTEM
,
3896 if (i
->need_daemon_reload
)
3897 warn_unit_file_changed(i
->id
);
3900 static void show_unit_help(UnitStatusInfo
*i
) {
3905 if (!i
->documentation
) {
3906 log_info("Documentation for %s not known.", i
->id
);
3910 STRV_FOREACH(p
, i
->documentation
)
3911 if (startswith(*p
, "man:"))
3912 show_man_page(*p
+ 4, false);
3914 log_info("Can't show: %s", *p
);
3917 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3924 switch (contents
[0]) {
3926 case SD_BUS_TYPE_STRING
: {
3929 r
= sd_bus_message_read(m
, "s", &s
);
3931 return bus_log_parse_error(r
);
3934 if (streq(name
, "Id"))
3936 else if (streq(name
, "LoadState"))
3938 else if (streq(name
, "ActiveState"))
3939 i
->active_state
= s
;
3940 else if (streq(name
, "SubState"))
3942 else if (streq(name
, "Description"))
3944 else if (streq(name
, "FragmentPath"))
3945 i
->fragment_path
= s
;
3946 else if (streq(name
, "SourcePath"))
3949 else if (streq(name
, "DefaultControlGroup")) {
3951 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3953 i
->control_group
= e
;
3956 else if (streq(name
, "ControlGroup"))
3957 i
->control_group
= s
;
3958 else if (streq(name
, "StatusText"))
3960 else if (streq(name
, "PIDFile"))
3962 else if (streq(name
, "SysFSPath"))
3964 else if (streq(name
, "Where"))
3966 else if (streq(name
, "What"))
3968 else if (streq(name
, "Following"))
3970 else if (streq(name
, "UnitFileState"))
3971 i
->unit_file_state
= s
;
3972 else if (streq(name
, "UnitFilePreset"))
3973 i
->unit_file_preset
= s
;
3974 else if (streq(name
, "Result"))
3981 case SD_BUS_TYPE_BOOLEAN
: {
3984 r
= sd_bus_message_read(m
, "b", &b
);
3986 return bus_log_parse_error(r
);
3988 if (streq(name
, "Accept"))
3990 else if (streq(name
, "NeedDaemonReload"))
3991 i
->need_daemon_reload
= b
;
3992 else if (streq(name
, "ConditionResult"))
3993 i
->condition_result
= b
;
3994 else if (streq(name
, "AssertResult"))
3995 i
->assert_result
= b
;
3996 else if (streq(name
, "Transient"))
4002 case SD_BUS_TYPE_UINT32
: {
4005 r
= sd_bus_message_read(m
, "u", &u
);
4007 return bus_log_parse_error(r
);
4009 if (streq(name
, "MainPID")) {
4011 i
->main_pid
= (pid_t
) u
;
4014 } else if (streq(name
, "ControlPID"))
4015 i
->control_pid
= (pid_t
) u
;
4016 else if (streq(name
, "ExecMainPID")) {
4018 i
->main_pid
= (pid_t
) u
;
4019 } else if (streq(name
, "NAccepted"))
4021 else if (streq(name
, "NConnections"))
4022 i
->n_connections
= u
;
4027 case SD_BUS_TYPE_INT32
: {
4030 r
= sd_bus_message_read(m
, "i", &j
);
4032 return bus_log_parse_error(r
);
4034 if (streq(name
, "ExecMainCode"))
4035 i
->exit_code
= (int) j
;
4036 else if (streq(name
, "ExecMainStatus"))
4037 i
->exit_status
= (int) j
;
4038 else if (streq(name
, "StatusErrno"))
4039 i
->status_errno
= (int) j
;
4044 case SD_BUS_TYPE_UINT64
: {
4047 r
= sd_bus_message_read(m
, "t", &u
);
4049 return bus_log_parse_error(r
);
4051 if (streq(name
, "ExecMainStartTimestamp"))
4052 i
->start_timestamp
= (usec_t
) u
;
4053 else if (streq(name
, "ExecMainExitTimestamp"))
4054 i
->exit_timestamp
= (usec_t
) u
;
4055 else if (streq(name
, "ActiveEnterTimestamp"))
4056 i
->active_enter_timestamp
= (usec_t
) u
;
4057 else if (streq(name
, "InactiveEnterTimestamp"))
4058 i
->inactive_enter_timestamp
= (usec_t
) u
;
4059 else if (streq(name
, "InactiveExitTimestamp"))
4060 i
->inactive_exit_timestamp
= (usec_t
) u
;
4061 else if (streq(name
, "InactiveExitTimestampMonotonic"))
4062 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
4063 else if (streq(name
, "ActiveExitTimestamp"))
4064 i
->active_exit_timestamp
= (usec_t
) u
;
4065 else if (streq(name
, "ConditionTimestamp"))
4066 i
->condition_timestamp
= (usec_t
) u
;
4067 else if (streq(name
, "AssertTimestamp"))
4068 i
->assert_timestamp
= (usec_t
) u
;
4069 else if (streq(name
, "MemoryCurrent"))
4070 i
->memory_current
= u
;
4071 else if (streq(name
, "MemoryLow"))
4073 else if (streq(name
, "MemoryHigh"))
4075 else if (streq(name
, "MemoryMax"))
4077 else if (streq(name
, "MemoryLimit"))
4078 i
->memory_limit
= u
;
4079 else if (streq(name
, "TasksCurrent"))
4080 i
->tasks_current
= u
;
4081 else if (streq(name
, "TasksMax"))
4083 else if (streq(name
, "CPUUsageNSec"))
4084 i
->cpu_usage_nsec
= u
;
4089 case SD_BUS_TYPE_ARRAY
:
4091 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4092 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
4094 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4096 return bus_log_parse_error(r
);
4098 info
= new0(ExecStatusInfo
, 1);
4102 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
4104 info
->name
= strdup(name
);
4108 LIST_PREPEND(exec
, i
->exec
, info
);
4110 info
= new0(ExecStatusInfo
, 1);
4116 return bus_log_parse_error(r
);
4118 r
= sd_bus_message_exit_container(m
);
4120 return bus_log_parse_error(r
);
4124 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4125 const char *type
, *path
;
4127 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4129 return bus_log_parse_error(r
);
4131 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
4133 r
= strv_extend(&i
->listen
, type
);
4137 r
= strv_extend(&i
->listen
, path
);
4142 return bus_log_parse_error(r
);
4144 r
= sd_bus_message_exit_container(m
);
4146 return bus_log_parse_error(r
);
4150 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
4152 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
4154 return bus_log_parse_error(r
);
4156 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4158 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4160 return bus_log_parse_error(r
);
4162 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4163 const char *cond
, *param
;
4164 int trigger
, negate
;
4167 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4169 return bus_log_parse_error(r
);
4171 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4172 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4173 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4174 i
->failed_condition
= cond
;
4175 i
->failed_condition_trigger
= trigger
;
4176 i
->failed_condition_negate
= negate
;
4177 i
->failed_condition_parameter
= param
;
4181 return bus_log_parse_error(r
);
4183 r
= sd_bus_message_exit_container(m
);
4185 return bus_log_parse_error(r
);
4187 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4188 const char *cond
, *param
;
4189 int trigger
, negate
;
4192 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4194 return bus_log_parse_error(r
);
4196 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4197 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4198 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4199 i
->failed_assert
= cond
;
4200 i
->failed_assert_trigger
= trigger
;
4201 i
->failed_assert_negate
= negate
;
4202 i
->failed_assert_parameter
= param
;
4206 return bus_log_parse_error(r
);
4208 r
= sd_bus_message_exit_container(m
);
4210 return bus_log_parse_error(r
);
4217 case SD_BUS_TYPE_STRUCT_BEGIN
:
4219 if (streq(name
, "LoadError")) {
4220 const char *n
, *message
;
4222 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4224 return bus_log_parse_error(r
);
4226 if (!isempty(message
))
4227 i
->load_error
= message
;
4240 r
= sd_bus_message_skip(m
, contents
);
4242 return bus_log_parse_error(r
);
4247 #define print_prop(name, fmt, ...) \
4250 printf(fmt "\n", __VA_ARGS__); \
4252 printf("%s=" fmt "\n", name, __VA_ARGS__); \
4255 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4261 /* This is a low-level property printer, see
4262 * print_status_info() for the nicer output */
4264 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4265 /* skip what we didn't read */
4266 r
= sd_bus_message_skip(m
, contents
);
4270 switch (contents
[0]) {
4272 case SD_BUS_TYPE_STRUCT_BEGIN
:
4274 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4277 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4279 return bus_log_parse_error(r
);
4282 print_prop(name
, "%"PRIu32
, u
);
4284 print_prop(name
, "%s", "");
4288 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4291 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4293 return bus_log_parse_error(r
);
4295 if (arg_all
|| !isempty(s
))
4296 print_prop(name
, "%s", s
);
4300 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4301 const char *a
= NULL
, *b
= NULL
;
4303 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4305 return bus_log_parse_error(r
);
4307 if (arg_all
|| !isempty(a
) || !isempty(b
))
4308 print_prop(name
, "%s \"%s\"", strempty(a
), strempty(b
));
4311 } else if (streq_ptr(name
, "SystemCallFilter")) {
4312 _cleanup_strv_free_
char **l
= NULL
;
4315 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4317 return bus_log_parse_error(r
);
4319 r
= sd_bus_message_read(m
, "b", &whitelist
);
4321 return bus_log_parse_error(r
);
4323 r
= sd_bus_message_read_strv(m
, &l
);
4325 return bus_log_parse_error(r
);
4327 r
= sd_bus_message_exit_container(m
);
4329 return bus_log_parse_error(r
);
4331 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4336 fputs(name
, stdout
);
4343 STRV_FOREACH(i
, l
) {
4351 fputc('\n', stdout
);
4359 case SD_BUS_TYPE_ARRAY
:
4361 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4365 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4367 return bus_log_parse_error(r
);
4369 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4370 print_prop("EnvironmentFile", "%s (ignore_errors=%s)", path
, yes_no(ignore
));
4373 return bus_log_parse_error(r
);
4375 r
= sd_bus_message_exit_container(m
);
4377 return bus_log_parse_error(r
);
4381 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4382 const char *type
, *path
;
4384 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4386 return bus_log_parse_error(r
);
4388 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4389 print_prop(type
, "%s", path
);
4391 return bus_log_parse_error(r
);
4393 r
= sd_bus_message_exit_container(m
);
4395 return bus_log_parse_error(r
);
4399 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4400 const char *type
, *path
;
4402 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4404 return bus_log_parse_error(r
);
4406 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4410 printf("Listen%s=%s\n", type
, path
);
4412 return bus_log_parse_error(r
);
4414 r
= sd_bus_message_exit_container(m
);
4416 return bus_log_parse_error(r
);
4420 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4422 uint64_t value
, next_elapse
;
4424 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4426 return bus_log_parse_error(r
);
4428 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4429 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4431 print_prop(base
, "{ value=%s ; next_elapse=%s }",
4432 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4433 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4436 return bus_log_parse_error(r
);
4438 r
= sd_bus_message_exit_container(m
);
4440 return bus_log_parse_error(r
);
4444 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4445 ExecStatusInfo info
= {};
4447 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4449 return bus_log_parse_error(r
);
4451 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4452 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4453 _cleanup_free_
char *tt
;
4455 tt
= strv_join(info
.argv
, " ");
4458 "{ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }",
4461 yes_no(info
.ignore
),
4462 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4463 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4465 sigchld_code_to_string(info
.code
),
4467 info
.code
== CLD_EXITED
? "" : "/",
4468 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4471 strv_free(info
.argv
);
4475 r
= sd_bus_message_exit_container(m
);
4477 return bus_log_parse_error(r
);
4481 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4482 const char *path
, *rwm
;
4484 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4486 return bus_log_parse_error(r
);
4488 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4489 print_prop(name
, "%s %s", strna(path
), strna(rwm
));
4491 return bus_log_parse_error(r
);
4493 r
= sd_bus_message_exit_container(m
);
4495 return bus_log_parse_error(r
);
4499 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "IODeviceWeight") || streq(name
, "BlockIODeviceWeight"))) {
4503 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4505 return bus_log_parse_error(r
);
4507 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4508 print_prop(name
, "%s %"PRIu64
, strna(path
), weight
);
4510 return bus_log_parse_error(r
);
4512 r
= sd_bus_message_exit_container(m
);
4514 return bus_log_parse_error(r
);
4518 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (cgroup_io_limit_type_from_string(name
) >= 0 ||
4519 streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4523 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4525 return bus_log_parse_error(r
);
4527 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4528 print_prop(name
, "%s %"PRIu64
, strna(path
), bandwidth
);
4530 return bus_log_parse_error(r
);
4532 r
= sd_bus_message_exit_container(m
);
4534 return bus_log_parse_error(r
);
4542 r
= bus_print_property(name
, m
, arg_value
, arg_all
);
4544 return bus_log_parse_error(r
);
4547 r
= sd_bus_message_skip(m
, contents
);
4549 return bus_log_parse_error(r
);
4552 printf("%s=[unprintable]\n", name
);
4558 static int show_one(
4563 bool show_properties
,
4567 static const struct bus_properties_map property_map
[] = {
4568 { "LoadState", "s", NULL
, offsetof(UnitStatusInfo
, load_state
) },
4569 { "ActiveState", "s", NULL
, offsetof(UnitStatusInfo
, active_state
) },
4573 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4574 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4575 _cleanup_set_free_ Set
*found_properties
= NULL
;
4576 UnitStatusInfo info
= {
4577 .memory_current
= (uint64_t) -1,
4578 .memory_high
= CGROUP_LIMIT_MAX
,
4579 .memory_max
= CGROUP_LIMIT_MAX
,
4580 .memory_limit
= (uint64_t) -1,
4581 .cpu_usage_nsec
= (uint64_t) -1,
4582 .tasks_current
= (uint64_t) -1,
4583 .tasks_max
= (uint64_t) -1,
4591 log_debug("Showing one %s", path
);
4593 r
= sd_bus_call_method(
4595 "org.freedesktop.systemd1",
4597 "org.freedesktop.DBus.Properties",
4603 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4606 r
= bus_message_map_all_properties(reply
, property_map
, &info
);
4608 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
4610 if (streq_ptr(info
.load_state
, "not-found") && streq_ptr(info
.active_state
, "inactive")) {
4611 log_error("Unit %s could not be found.", unit
);
4613 if (streq(verb
, "status"))
4614 return EXIT_PROGRAM_OR_SERVICES_STATUS_UNKNOWN
;
4619 r
= sd_bus_message_rewind(reply
, true);
4621 return log_error_errno(r
, "Failed to rewind: %s", bus_error_message(&error
, r
));
4624 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4626 return bus_log_parse_error(r
);
4633 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4634 const char *name
, *contents
;
4636 r
= sd_bus_message_read(reply
, "s", &name
);
4638 return bus_log_parse_error(r
);
4640 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4642 return bus_log_parse_error(r
);
4644 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4646 return bus_log_parse_error(r
);
4648 if (show_properties
) {
4649 r
= set_ensure_allocated(&found_properties
, &string_hash_ops
);
4653 r
= set_put(found_properties
, name
);
4654 if (r
< 0 && r
!= EEXIST
)
4657 r
= print_property(name
, reply
, contents
);
4659 r
= status_property(name
, reply
, &info
, contents
);
4663 r
= sd_bus_message_exit_container(reply
);
4665 return bus_log_parse_error(r
);
4667 r
= sd_bus_message_exit_container(reply
);
4669 return bus_log_parse_error(r
);
4672 return bus_log_parse_error(r
);
4674 r
= sd_bus_message_exit_container(reply
);
4676 return bus_log_parse_error(r
);
4680 if (show_properties
) {
4683 STRV_FOREACH(pp
, arg_properties
) {
4684 if (!set_contains(found_properties
, *pp
)) {
4685 log_warning("Property %s does not exist.", *pp
);
4689 } else if (streq(verb
, "help"))
4690 show_unit_help(&info
);
4691 else if (streq(verb
, "status")) {
4692 print_status_info(bus
, &info
, ellipsized
);
4694 if (info
.active_state
&& STR_IN_SET(info
.active_state
, "inactive", "failed"))
4695 r
= EXIT_PROGRAM_NOT_RUNNING
;
4697 r
= EXIT_PROGRAM_RUNNING_OR_SERVICE_OK
;
4700 strv_free(info
.documentation
);
4701 strv_free(info
.dropin_paths
);
4702 strv_free(info
.listen
);
4704 while ((p
= info
.exec
)) {
4705 LIST_REMOVE(exec
, info
.exec
, p
);
4706 exec_status_info_free(p
);
4712 static int get_unit_dbus_path_by_pid(
4717 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4718 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4722 r
= sd_bus_call_method(
4724 "org.freedesktop.systemd1",
4725 "/org/freedesktop/systemd1",
4726 "org.freedesktop.systemd1.Manager",
4732 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4734 r
= sd_bus_message_read(reply
, "o", &u
);
4736 return bus_log_parse_error(r
);
4746 static int show_all(
4749 bool show_properties
,
4753 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4754 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4759 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4763 pager_open(arg_no_pager
, false);
4767 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4769 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4770 _cleanup_free_
char *p
= NULL
;
4772 p
= unit_dbus_path_from_name(u
->id
);
4776 r
= show_one(verb
, bus
, p
, u
->id
, show_properties
, new_line
, ellipsized
);
4779 else if (r
> 0 && ret
== 0)
4786 static int show_system_status(sd_bus
*bus
) {
4787 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4788 _cleanup_free_
char *hn
= NULL
;
4789 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4790 const char *on
, *off
;
4793 hn
= gethostname_malloc();
4797 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4799 return log_error_errno(r
, "Failed to read server status: %m");
4801 if (streq_ptr(mi
.state
, "degraded")) {
4802 on
= ansi_highlight_red();
4803 off
= ansi_normal();
4804 } else if (!streq_ptr(mi
.state
, "running")) {
4805 on
= ansi_highlight_yellow();
4806 off
= ansi_normal();
4810 printf("%s%s%s %s\n", on
, special_glyph(BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4812 printf(" State: %s%s%s\n",
4813 on
, strna(mi
.state
), off
);
4815 printf(" Jobs: %" PRIu32
" queued\n", mi
.n_jobs
);
4816 printf(" Failed: %" PRIu32
" units\n", mi
.n_failed_units
);
4818 printf(" Since: %s; %s\n",
4819 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4820 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4822 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4823 if (IN_SET(arg_transport
,
4824 BUS_TRANSPORT_LOCAL
,
4825 BUS_TRANSPORT_MACHINE
)) {
4826 static const char prefix
[] = " ";
4830 if (c
> sizeof(prefix
) - 1)
4831 c
-= sizeof(prefix
) - 1;
4835 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, get_output_flags());
4841 static int show(int argc
, char *argv
[], void *userdata
) {
4842 bool show_properties
, show_status
, show_help
, new_line
= false;
4843 bool ellipsized
= false;
4849 show_properties
= streq(argv
[0], "show");
4850 show_status
= streq(argv
[0], "status");
4851 show_help
= streq(argv
[0], "help");
4853 if (show_help
&& argc
<= 1) {
4854 log_error("This command expects one or more unit names. Did you mean --help?");
4858 r
= acquire_bus(BUS_MANAGER
, &bus
);
4862 pager_open(arg_no_pager
, false);
4865 /* Increase max number of open files to 16K if we can, we
4866 * might needs this when browsing journal files, which might
4867 * be split up into many files. */
4868 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4870 /* If no argument is specified inspect the manager itself */
4871 if (show_properties
&& argc
<= 1)
4872 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", NULL
, show_properties
, &new_line
, &ellipsized
);
4874 if (show_status
&& argc
<= 1) {
4876 show_system_status(bus
);
4880 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4882 _cleanup_free_
char **patterns
= NULL
;
4885 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4886 _cleanup_free_
char *path
= NULL
, *unit
= NULL
;
4889 if (safe_atou32(*name
, &id
) < 0) {
4890 if (strv_push(&patterns
, *name
) < 0)
4894 } else if (show_properties
) {
4895 /* Interpret as job id */
4896 if (asprintf(&path
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4900 /* Interpret as PID */
4901 r
= get_unit_dbus_path_by_pid(bus
, id
, &path
);
4907 r
= unit_name_from_dbus_path(path
, &unit
);
4912 r
= show_one(argv
[0], bus
, path
, unit
, show_properties
, &new_line
, &ellipsized
);
4915 else if (r
> 0 && ret
== 0)
4919 if (!strv_isempty(patterns
)) {
4920 _cleanup_strv_free_
char **names
= NULL
;
4922 r
= expand_names(bus
, patterns
, NULL
, &names
);
4924 return log_error_errno(r
, "Failed to expand names: %m");
4926 STRV_FOREACH(name
, names
) {
4927 _cleanup_free_
char *path
;
4929 path
= unit_dbus_path_from_name(*name
);
4933 r
= show_one(argv
[0], bus
, path
, *name
, show_properties
, &new_line
, &ellipsized
);
4936 if (r
> 0 && ret
== 0)
4942 if (ellipsized
&& !arg_quiet
)
4943 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4948 static int cat_file(const char *filename
, bool newline
) {
4949 _cleanup_close_
int fd
;
4951 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4955 printf("%s%s# %s%s\n",
4956 newline
? "\n" : "",
4957 ansi_highlight_blue(),
4962 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4965 static int cat(int argc
, char *argv
[], void *userdata
) {
4966 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4967 _cleanup_strv_free_
char **names
= NULL
;
4973 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4974 log_error("Cannot remotely cat units.");
4978 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
4980 return log_error_errno(r
, "Failed to determine unit paths: %m");
4982 r
= acquire_bus(BUS_MANAGER
, &bus
);
4986 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4988 return log_error_errno(r
, "Failed to expand names: %m");
4990 pager_open(arg_no_pager
, false);
4992 STRV_FOREACH(name
, names
) {
4993 _cleanup_free_
char *fragment_path
= NULL
;
4994 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4997 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
5008 if (fragment_path
) {
5009 r
= cat_file(fragment_path
, false);
5011 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
5014 STRV_FOREACH(path
, dropin_paths
) {
5015 r
= cat_file(*path
, path
== dropin_paths
);
5017 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
5024 static int set_property(int argc
, char *argv
[], void *userdata
) {
5025 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5026 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5027 _cleanup_free_
char *n
= NULL
;
5032 r
= acquire_bus(BUS_MANAGER
, &bus
);
5036 polkit_agent_open_if_enabled();
5038 r
= sd_bus_message_new_method_call(
5041 "org.freedesktop.systemd1",
5042 "/org/freedesktop/systemd1",
5043 "org.freedesktop.systemd1.Manager",
5044 "SetUnitProperties");
5046 return bus_log_create_error(r
);
5048 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
5050 return log_error_errno(r
, "Failed to mangle unit name: %m");
5052 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
5054 return bus_log_create_error(r
);
5056 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
5058 return bus_log_create_error(r
);
5060 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
5061 r
= bus_append_unit_property_assignment(m
, *i
);
5066 r
= sd_bus_message_close_container(m
);
5068 return bus_log_create_error(r
);
5070 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5072 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
5077 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
5078 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5079 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5084 r
= acquire_bus(BUS_MANAGER
, &bus
);
5088 polkit_agent_open_if_enabled();
5090 switch (arg_action
) {
5097 method
= "Reexecute";
5100 case ACTION_SYSTEMCTL
:
5101 method
= streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5102 /* "daemon-reload" */ "Reload";
5106 assert_not_reached("Unexpected action");
5109 r
= sd_bus_message_new_method_call(
5112 "org.freedesktop.systemd1",
5113 "/org/freedesktop/systemd1",
5114 "org.freedesktop.systemd1.Manager",
5117 return bus_log_create_error(r
);
5119 /* Note we use an extra-long timeout here. This is because a reload or reexec means generators are rerun which
5120 * are timed out after DEFAULT_TIMEOUT_USEC. Let's use twice that time here, so that the generators can have
5121 * their timeout, and for everything else there's the same time budget in place. */
5123 r
= sd_bus_call(bus
, m
, DEFAULT_TIMEOUT_USEC
* 2, &error
, NULL
);
5125 /* On reexecution, we expect a disconnect, not a reply */
5126 if (IN_SET(r
, -ETIMEDOUT
, -ECONNRESET
) && streq(method
, "Reexecute"))
5129 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5130 return log_error_errno(r
, "Failed to reload daemon: %s", bus_error_message(&error
, r
));
5132 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5133 * old ways of doing things, hence don't log any error in that case here. */
5135 return r
< 0 ? r
: 0;
5138 static int trivial_method(int argc
, char *argv
[], void *userdata
) {
5139 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5144 r
= acquire_bus(BUS_MANAGER
, &bus
);
5148 polkit_agent_open_if_enabled();
5151 streq(argv
[0], "clear-jobs") ||
5152 streq(argv
[0], "cancel") ? "ClearJobs" :
5153 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5154 streq(argv
[0], "halt") ? "Halt" :
5155 streq(argv
[0], "reboot") ? "Reboot" :
5156 streq(argv
[0], "kexec") ? "KExec" :
5157 streq(argv
[0], "exit") ? "Exit" :
5158 /* poweroff */ "PowerOff";
5160 r
= sd_bus_call_method(
5162 "org.freedesktop.systemd1",
5163 "/org/freedesktop/systemd1",
5164 "org.freedesktop.systemd1.Manager",
5169 if (r
< 0 && arg_action
== ACTION_SYSTEMCTL
)
5170 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5172 /* Note that for the legacy commands (i.e. those with action != ACTION_SYSTEMCTL) we support fallbacks to the
5173 * old ways of doing things, hence don't log any error in that case here. */
5175 return r
< 0 ? r
: 0;
5178 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5179 _cleanup_strv_free_
char **names
= NULL
;
5185 return trivial_method(argc
, argv
, userdata
);
5187 r
= acquire_bus(BUS_MANAGER
, &bus
);
5191 polkit_agent_open_if_enabled();
5193 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5195 return log_error_errno(r
, "Failed to expand names: %m");
5197 STRV_FOREACH(name
, names
) {
5198 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5200 q
= sd_bus_call_method(
5202 "org.freedesktop.systemd1",
5203 "/org/freedesktop/systemd1",
5204 "org.freedesktop.systemd1.Manager",
5210 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5219 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5220 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5221 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5226 r
= acquire_bus(BUS_MANAGER
, &bus
);
5230 pager_open(arg_no_pager
, false);
5232 r
= sd_bus_get_property(
5234 "org.freedesktop.systemd1",
5235 "/org/freedesktop/systemd1",
5236 "org.freedesktop.systemd1.Manager",
5242 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5244 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5246 return bus_log_parse_error(r
);
5248 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5251 return bus_log_parse_error(r
);
5253 r
= sd_bus_message_exit_container(reply
);
5255 return bus_log_parse_error(r
);
5260 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5261 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5262 _cleanup_free_
char *cmdline_init
= NULL
;
5263 const char *root
, *init
;
5267 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5268 log_error("Cannot switch root remotely.");
5272 if (argc
< 2 || argc
> 3) {
5273 log_error("Wrong number of arguments.");
5282 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5283 "init", &cmdline_init
,
5286 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5288 init
= cmdline_init
;
5291 init
= empty_to_null(init
);
5293 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5295 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5296 root_init_path
= strjoina(root
, "/", init
);
5298 /* If the passed init is actually the same as the
5299 * systemd binary, then let's suppress it. */
5300 if (files_same(root_init_path
, root_systemd_path
) > 0)
5304 r
= acquire_bus(BUS_MANAGER
, &bus
);
5308 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5310 r
= sd_bus_call_method(
5312 "org.freedesktop.systemd1",
5313 "/org/freedesktop/systemd1",
5314 "org.freedesktop.systemd1.Manager",
5320 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5325 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5326 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5327 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5335 r
= acquire_bus(BUS_MANAGER
, &bus
);
5339 polkit_agent_open_if_enabled();
5341 method
= streq(argv
[0], "set-environment")
5343 : "UnsetEnvironment";
5345 r
= sd_bus_message_new_method_call(
5348 "org.freedesktop.systemd1",
5349 "/org/freedesktop/systemd1",
5350 "org.freedesktop.systemd1.Manager",
5353 return bus_log_create_error(r
);
5355 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5357 return bus_log_create_error(r
);
5359 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5361 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5366 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5367 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5368 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5372 r
= acquire_bus(BUS_MANAGER
, &bus
);
5376 polkit_agent_open_if_enabled();
5378 r
= sd_bus_message_new_method_call(
5381 "org.freedesktop.systemd1",
5382 "/org/freedesktop/systemd1",
5383 "org.freedesktop.systemd1.Manager",
5386 return bus_log_create_error(r
);
5389 r
= sd_bus_message_append_strv(m
, environ
);
5393 r
= sd_bus_message_open_container(m
, 'a', "s");
5395 return bus_log_create_error(r
);
5397 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5399 if (!env_name_is_valid(*a
)) {
5400 log_error("Not a valid environment variable name: %s", *a
);
5404 STRV_FOREACH(b
, environ
) {
5407 eq
= startswith(*b
, *a
);
5408 if (eq
&& *eq
== '=') {
5410 r
= sd_bus_message_append(m
, "s", *b
);
5412 return bus_log_create_error(r
);
5419 r
= sd_bus_message_close_container(m
);
5422 return bus_log_create_error(r
);
5424 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5426 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5431 static int enable_sysv_units(const char *verb
, char **args
) {
5434 #if defined(HAVE_SYSV_COMPAT)
5435 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5438 /* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
5440 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5443 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5446 if (!STR_IN_SET(verb
,
5452 r
= lookup_paths_init(&paths
, arg_scope
, LOOKUP_PATHS_EXCLUDE_GENERATED
, arg_root
);
5459 const char *argv
[] = {
5460 ROOTLIBEXECDIR
"/systemd-sysv-install",
5467 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5468 bool found_native
= false, found_sysv
;
5477 if (!endswith(name
, ".service"))
5480 if (path_is_absolute(name
))
5483 j
= unit_file_exists(arg_scope
, &paths
, name
);
5484 if (j
< 0 && !IN_SET(j
, -ELOOP
, -ERFKILL
, -EADDRNOTAVAIL
))
5485 return log_error_errno(j
, "Failed to lookup unit file state: %m");
5486 found_native
= j
!= 0;
5488 /* If we have both a native unit and a SysV script, enable/disable them both (below); for is-enabled,
5489 * prefer the native unit */
5490 if (found_native
&& streq(verb
, "is-enabled"))
5493 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5497 p
[strlen(p
) - strlen(".service")] = 0;
5498 found_sysv
= access(p
, F_OK
) >= 0;
5503 log_info("Synchronizing state of %s with SysV service script with %s.", name
, argv
[0]);
5505 log_info("%s is not a native service, redirecting to systemd-sysv-install.", name
);
5507 if (!isempty(arg_root
))
5508 argv
[c
++] = q
= strappend("--root=", arg_root
);
5511 argv
[c
++] = basename(p
);
5514 l
= strv_join((char**)argv
, " ");
5518 log_info("Executing: %s", l
);
5522 return log_error_errno(errno
, "Failed to fork: %m");
5523 else if (pid
== 0) {
5526 (void) reset_all_signal_handlers();
5527 (void) reset_signal_mask();
5529 execv(argv
[0], (char**) argv
);
5530 log_error_errno(errno
, "Failed to execute %s: %m", argv
[0]);
5531 _exit(EXIT_FAILURE
);
5534 j
= wait_for_terminate(pid
, &status
);
5536 log_error_errno(j
, "Failed to wait for child: %m");
5540 if (status
.si_code
== CLD_EXITED
) {
5541 if (streq(verb
, "is-enabled")) {
5542 if (status
.si_status
== 0) {
5551 } else if (status
.si_status
!= 0)
5552 return -EBADE
; /* We don't warn here, under the assumption the script already showed an explanation */
5554 log_error("Unexpected waitid() result.");
5561 /* Remove this entry, so that we don't try enabling it as native unit */
5564 assert(args
[f
] == name
);
5565 strv_remove(args
, name
);
5572 static int mangle_names(char **original_names
, char ***mangled_names
) {
5573 char **i
, **l
, **name
;
5576 l
= i
= new(char*, strv_length(original_names
) + 1);
5580 STRV_FOREACH(name
, original_names
) {
5582 /* When enabling units qualified path names are OK,
5583 * too, hence allow them explicitly. */
5585 if (is_path(*name
)) {
5592 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5595 return log_error_errno(r
, "Failed to mangle unit name: %m");
5608 static int unit_exists(const char *unit
) {
5609 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5610 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5611 _cleanup_free_
char *path
= NULL
;
5612 static const struct bus_properties_map property_map
[] = {
5613 { "LoadState", "s", NULL
, offsetof(UnitStatusInfo
, load_state
) },
5614 { "ActiveState", "s", NULL
, offsetof(UnitStatusInfo
, active_state
)},
5617 UnitStatusInfo info
= {};
5621 path
= unit_dbus_path_from_name(unit
);
5625 r
= acquire_bus(BUS_MANAGER
, &bus
);
5629 r
= sd_bus_call_method(
5631 "org.freedesktop.systemd1",
5633 "org.freedesktop.DBus.Properties",
5639 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
5641 r
= bus_message_map_all_properties(reply
, property_map
, &info
);
5643 return log_error_errno(r
, "Failed to map properties: %s", bus_error_message(&error
, r
));
5645 return !streq_ptr(info
.load_state
, "not-found") || !streq_ptr(info
.active_state
, "inactive");
5648 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5649 _cleanup_strv_free_
char **names
= NULL
;
5650 const char *verb
= argv
[0];
5651 UnitFileChange
*changes
= NULL
;
5652 unsigned n_changes
= 0;
5653 int carries_install_info
= -1;
5654 bool ignore_carries_install_info
= arg_quiet
;
5660 r
= mangle_names(strv_skip(argv
, 1), &names
);
5664 r
= enable_sysv_units(verb
, names
);
5668 /* If the operation was fully executed by the SysV compat, let's finish early */
5669 if (strv_isempty(names
)) {
5670 if (arg_no_reload
|| install_client_side())
5672 return daemon_reload(argc
, argv
, userdata
);
5675 if (install_client_side()) {
5676 if (streq(verb
, "enable")) {
5677 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5678 carries_install_info
= r
;
5679 } else if (streq(verb
, "disable"))
5680 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5681 else if (streq(verb
, "reenable")) {
5682 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5683 carries_install_info
= r
;
5684 } else if (streq(verb
, "link"))
5685 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5686 else if (streq(verb
, "preset")) {
5687 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5688 } else if (streq(verb
, "mask"))
5689 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5690 else if (streq(verb
, "unmask"))
5691 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5692 else if (streq(verb
, "revert"))
5693 r
= unit_file_revert(arg_scope
, arg_root
, names
, &changes
, &n_changes
);
5695 assert_not_reached("Unknown verb");
5697 unit_file_dump_changes(r
, verb
, changes
, n_changes
, arg_quiet
);
5702 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5703 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5704 bool expect_carries_install_info
= false;
5705 bool send_runtime
= true, send_force
= true, send_preset_mode
= false;
5709 if (STR_IN_SET(verb
, "mask", "unmask")) {
5710 r
= unit_exists(*names
);
5714 log_notice("Unit %s does not exist, proceeding anyway.", *names
);
5717 r
= acquire_bus(BUS_MANAGER
, &bus
);
5721 polkit_agent_open_if_enabled();
5723 if (streq(verb
, "enable")) {
5724 method
= "EnableUnitFiles";
5725 expect_carries_install_info
= true;
5726 } else if (streq(verb
, "disable")) {
5727 method
= "DisableUnitFiles";
5729 } else if (streq(verb
, "reenable")) {
5730 method
= "ReenableUnitFiles";
5731 expect_carries_install_info
= true;
5732 } else if (streq(verb
, "link"))
5733 method
= "LinkUnitFiles";
5734 else if (streq(verb
, "preset")) {
5736 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5737 method
= "PresetUnitFilesWithMode";
5738 send_preset_mode
= true;
5740 method
= "PresetUnitFiles";
5742 expect_carries_install_info
= true;
5743 ignore_carries_install_info
= true;
5744 } else if (streq(verb
, "mask"))
5745 method
= "MaskUnitFiles";
5746 else if (streq(verb
, "unmask")) {
5747 method
= "UnmaskUnitFiles";
5749 } else if (streq(verb
, "revert")) {
5750 method
= "RevertUnitFiles";
5751 send_runtime
= send_force
= false;
5753 assert_not_reached("Unknown verb");
5755 r
= sd_bus_message_new_method_call(
5758 "org.freedesktop.systemd1",
5759 "/org/freedesktop/systemd1",
5760 "org.freedesktop.systemd1.Manager",
5763 return bus_log_create_error(r
);
5765 r
= sd_bus_message_append_strv(m
, names
);
5767 return bus_log_create_error(r
);
5769 if (send_preset_mode
) {
5770 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5772 return bus_log_create_error(r
);
5776 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5778 return bus_log_create_error(r
);
5782 r
= sd_bus_message_append(m
, "b", arg_force
);
5784 return bus_log_create_error(r
);
5787 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5789 return log_error_errno(r
, "Failed to %s unit: %s", verb
, bus_error_message(&error
, r
));
5791 if (expect_carries_install_info
) {
5792 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5794 return bus_log_parse_error(r
);
5797 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5801 /* Try to reload if enabled */
5803 r
= daemon_reload(argc
, argv
, userdata
);
5808 if (carries_install_info
== 0 && !ignore_carries_install_info
)
5809 log_warning("The unit files have no installation config (WantedBy, RequiredBy, Also, Alias\n"
5810 "settings in the [Install] section, and DefaultInstance for template units).\n"
5811 "This means they are not meant to be enabled using systemctl.\n"
5812 "Possible reasons for having this kind of units are:\n"
5813 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5814 " .wants/ or .requires/ directory.\n"
5815 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5816 " a requirement dependency on it.\n"
5817 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5818 " D-Bus, udev, scripted systemctl call, ...).\n"
5819 "4) In case of template units, the unit is meant to be enabled with some\n"
5820 " instance name specified.");
5822 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5823 char *new_args
[n_changes
+ 2];
5827 r
= acquire_bus(BUS_MANAGER
, &bus
);
5831 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5832 for (i
= 0; i
< n_changes
; i
++)
5833 new_args
[i
+ 1] = basename(changes
[i
].path
);
5834 new_args
[i
+ 1] = NULL
;
5836 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5840 unit_file_changes_free(changes
, n_changes
);
5845 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5846 _cleanup_strv_free_
char **names
= NULL
;
5847 _cleanup_free_
char *target
= NULL
;
5848 const char *verb
= argv
[0];
5849 UnitFileChange
*changes
= NULL
;
5850 unsigned n_changes
= 0;
5857 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5859 return log_error_errno(r
, "Failed to mangle unit name: %m");
5861 r
= mangle_names(strv_skip(argv
, 2), &names
);
5865 if (streq(verb
, "add-wants"))
5867 else if (streq(verb
, "add-requires"))
5868 dep
= UNIT_REQUIRES
;
5870 assert_not_reached("Unknown verb");
5872 if (install_client_side()) {
5873 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5874 unit_file_dump_changes(r
, "add dependency on", changes
, n_changes
, arg_quiet
);
5879 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5880 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5883 r
= acquire_bus(BUS_MANAGER
, &bus
);
5887 polkit_agent_open_if_enabled();
5889 r
= sd_bus_message_new_method_call(
5892 "org.freedesktop.systemd1",
5893 "/org/freedesktop/systemd1",
5894 "org.freedesktop.systemd1.Manager",
5895 "AddDependencyUnitFiles");
5897 return bus_log_create_error(r
);
5899 r
= sd_bus_message_append_strv(m
, names
);
5901 return bus_log_create_error(r
);
5903 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5905 return bus_log_create_error(r
);
5907 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5909 return log_error_errno(r
, "Failed to add dependency: %s", bus_error_message(&error
, r
));
5911 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5915 if (arg_no_reload
) {
5920 r
= daemon_reload(argc
, argv
, userdata
);
5924 unit_file_changes_free(changes
, n_changes
);
5929 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5930 UnitFileChange
*changes
= NULL
;
5931 unsigned n_changes
= 0;
5934 if (install_client_side()) {
5935 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5936 unit_file_dump_changes(r
, "preset", changes
, n_changes
, arg_quiet
);
5941 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5942 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5945 r
= acquire_bus(BUS_MANAGER
, &bus
);
5949 polkit_agent_open_if_enabled();
5951 r
= sd_bus_call_method(
5953 "org.freedesktop.systemd1",
5954 "/org/freedesktop/systemd1",
5955 "org.freedesktop.systemd1.Manager",
5956 "PresetAllUnitFiles",
5960 unit_file_preset_mode_to_string(arg_preset_mode
),
5964 return log_error_errno(r
, "Failed to preset all units: %s", bus_error_message(&error
, r
));
5966 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5970 if (arg_no_reload
) {
5975 r
= daemon_reload(argc
, argv
, userdata
);
5979 unit_file_changes_free(changes
, n_changes
);
5984 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5986 _cleanup_strv_free_
char **names
= NULL
;
5991 r
= mangle_names(strv_skip(argv
, 1), &names
);
5995 r
= enable_sysv_units(argv
[0], names
);
6001 if (install_client_side()) {
6003 STRV_FOREACH(name
, names
) {
6004 UnitFileState state
;
6006 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
6008 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
6012 UNIT_FILE_ENABLED_RUNTIME
,
6015 UNIT_FILE_GENERATED
))
6019 puts(unit_file_state_to_string(state
));
6024 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
6027 r
= acquire_bus(BUS_MANAGER
, &bus
);
6031 STRV_FOREACH(name
, names
) {
6032 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
6035 r
= sd_bus_call_method(
6037 "org.freedesktop.systemd1",
6038 "/org/freedesktop/systemd1",
6039 "org.freedesktop.systemd1.Manager",
6045 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
6047 r
= sd_bus_message_read(reply
, "s", &s
);
6049 return bus_log_parse_error(r
);
6051 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect", "generated"))
6059 return enabled
? EXIT_SUCCESS
: EXIT_FAILURE
;
6062 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
6063 _cleanup_free_
char *state
= NULL
;
6067 if (running_in_chroot() > 0 || (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted())) {
6070 return EXIT_FAILURE
;
6073 r
= acquire_bus(BUS_MANAGER
, &bus
);
6077 r
= sd_bus_get_property_string(
6079 "org.freedesktop.systemd1",
6080 "/org/freedesktop/systemd1",
6081 "org.freedesktop.systemd1.Manager",
6094 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
6097 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
6098 _cleanup_free_
char *t
= NULL
;
6102 assert(original_path
);
6105 r
= tempfn_random(new_path
, NULL
, &t
);
6107 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
6109 r
= mkdir_parents(new_path
, 0755);
6111 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
6113 r
= copy_file(original_path
, t
, 0, 0644, 0);
6118 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
6121 return log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", new_path
);
6129 static int get_file_to_edit(
6130 const LookupPaths
*paths
,
6134 _cleanup_free_
char *path
= NULL
, *run
= NULL
;
6139 path
= strjoin(paths
->persistent_config
, "/", name
, NULL
);
6144 run
= strjoin(paths
->runtime_config
, "/", name
, NULL
);
6150 if (access(path
, F_OK
) >= 0) {
6151 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
6165 static int unit_file_create_new(
6166 const LookupPaths
*paths
,
6167 const char *unit_name
,
6169 char **ret_new_path
,
6170 char **ret_tmp_path
) {
6172 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6176 assert(ret_new_path
);
6177 assert(ret_tmp_path
);
6179 ending
= strjoina(unit_name
, suffix
);
6180 r
= get_file_to_edit(paths
, ending
, &tmp_new_path
);
6184 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6190 *ret_new_path
= tmp_new_path
;
6191 *ret_tmp_path
= tmp_tmp_path
;
6196 static int unit_file_create_copy(
6197 const LookupPaths
*paths
,
6198 const char *unit_name
,
6199 const char *fragment_path
,
6200 char **ret_new_path
,
6201 char **ret_tmp_path
) {
6203 char *tmp_new_path
, *tmp_tmp_path
;
6206 assert(fragment_path
);
6208 assert(ret_new_path
);
6209 assert(ret_tmp_path
);
6211 r
= get_file_to_edit(paths
, unit_name
, &tmp_new_path
);
6215 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6218 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6223 if (response
!= 'y') {
6224 log_warning("%s ignored", unit_name
);
6226 return -EKEYREJECTED
;
6230 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6236 *ret_new_path
= tmp_new_path
;
6237 *ret_tmp_path
= tmp_tmp_path
;
6242 static int run_editor(char **paths
) {
6250 return log_error_errno(errno
, "Failed to fork: %m");
6254 char *editor
, **editor_args
= NULL
;
6255 char **tmp_path
, **original_path
, *p
;
6256 unsigned n_editor_args
= 0, i
= 1;
6259 (void) reset_all_signal_handlers();
6260 (void) reset_signal_mask();
6262 argc
= strv_length(paths
)/2 + 1;
6264 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6265 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6266 * we try to execute well known editors
6268 editor
= getenv("SYSTEMD_EDITOR");
6270 editor
= getenv("EDITOR");
6272 editor
= getenv("VISUAL");
6274 if (!isempty(editor
)) {
6275 editor_args
= strv_split(editor
, WHITESPACE
);
6278 _exit(EXIT_FAILURE
);
6280 n_editor_args
= strv_length(editor_args
);
6281 argc
+= n_editor_args
- 1;
6283 args
= newa(const char*, argc
+ 1);
6285 if (n_editor_args
> 0) {
6286 args
[0] = editor_args
[0];
6287 for (; i
< n_editor_args
; i
++)
6288 args
[i
] = editor_args
[i
];
6291 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6292 args
[i
] = *tmp_path
;
6297 if (n_editor_args
> 0)
6298 execvp(args
[0], (char* const*) args
);
6300 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6302 execvp(p
, (char* const*) args
);
6303 /* We do not fail if the editor doesn't exist
6304 * because we want to try each one of them before
6307 if (errno
!= ENOENT
) {
6308 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6309 _exit(EXIT_FAILURE
);
6313 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6314 _exit(EXIT_FAILURE
);
6317 r
= wait_for_terminate_and_warn("editor", pid
, true);
6319 return log_error_errno(r
, "Failed to wait for child: %m");
6324 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6325 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6332 r
= lookup_paths_init(&lp
, arg_scope
, 0, arg_root
);
6336 STRV_FOREACH(name
, names
) {
6337 _cleanup_free_
char *path
= NULL
, *new_path
= NULL
, *tmp_path
= NULL
;
6339 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6342 else if (!arg_force
) {
6344 log_error("Run 'systemctl edit --force %s' to create a new unit.", *name
);
6347 // FIXME: support units with path==NULL (no FragmentPath)
6348 log_error("No fragment exists for %s.", *name
);
6355 r
= unit_file_create_copy(&lp
, *name
, path
, &new_path
, &tmp_path
);
6357 r
= unit_file_create_new(&lp
, *name
, ".d/override.conf", &new_path
, &tmp_path
);
6359 r
= unit_file_create_new(&lp
, *name
, NULL
, &new_path
, &tmp_path
);
6363 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6366 new_path
= tmp_path
= NULL
;
6372 static int edit(int argc
, char *argv
[], void *userdata
) {
6373 _cleanup_strv_free_
char **names
= NULL
;
6374 _cleanup_strv_free_
char **paths
= NULL
;
6375 char **original
, **tmp
;
6380 log_error("Cannot edit units if not on a tty.");
6384 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6385 log_error("Cannot edit units remotely.");
6389 r
= acquire_bus(BUS_MANAGER
, &bus
);
6393 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6395 return log_error_errno(r
, "Failed to expand names: %m");
6397 r
= find_paths_to_edit(bus
, names
, &paths
);
6401 if (strv_isempty(paths
))
6404 r
= run_editor(paths
);
6408 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6409 /* If the temporary file is empty we ignore it. It's
6410 * useful if the user wants to cancel its modification
6412 if (null_or_empty_path(*tmp
)) {
6413 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6417 r
= rename(*tmp
, *original
);
6419 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6426 if (!arg_no_reload
&& !install_client_side())
6427 r
= daemon_reload(argc
, argv
, userdata
);
6430 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6431 (void) unlink(*tmp
);
6433 /* Removing empty dropin dirs */
6435 _cleanup_free_
char *dir
;
6437 dir
= dirname_malloc(*original
);
6441 /* no need to check if the dir is empty, rmdir
6442 * does nothing if it is not the case.
6451 static void systemctl_help(void) {
6453 pager_open(arg_no_pager
, false);
6455 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6456 "Query or send control commands to the systemd manager.\n\n"
6457 " -h --help Show this help\n"
6458 " --version Show package version\n"
6459 " --system Connect to system manager\n"
6460 " --user Connect to user service manager\n"
6461 " -H --host=[USER@]HOST\n"
6462 " Operate on remote host\n"
6463 " -M --machine=CONTAINER\n"
6464 " Operate on local container\n"
6465 " -t --type=TYPE List units of a particular type\n"
6466 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6467 " -p --property=NAME Show only properties by this name\n"
6468 " -a --all Show all loaded units/properties, including dead/empty\n"
6469 " ones. To list all units installed on the system, use\n"
6470 " the 'list-unit-files' command instead.\n"
6471 " -l --full Don't ellipsize unit names on output\n"
6472 " -r --recursive Show unit list of host and local containers\n"
6473 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6474 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6475 " queueing a new job\n"
6476 " --show-types When showing sockets, explicitly show their type\n"
6477 " --value When showing properties, only print the value\n"
6478 " -i --ignore-inhibitors\n"
6479 " When shutting down or sleeping, ignore inhibitors\n"
6480 " --kill-who=WHO Who to send signal to\n"
6481 " -s --signal=SIGNAL Which signal to send\n"
6482 " --now Start or stop unit in addition to enabling or disabling it\n"
6483 " -q --quiet Suppress output\n"
6484 " --no-block Do not wait until operation finished\n"
6485 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6486 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6487 " --no-legend Do not print a legend (column headers and hints)\n"
6488 " --no-pager Do not pipe output into a pager\n"
6489 " --no-ask-password\n"
6490 " Do not ask for system passwords\n"
6491 " --global Enable/disable unit files globally\n"
6492 " --runtime Enable unit files only temporarily until next reboot\n"
6493 " -f --force When enabling unit files, override existing symlinks\n"
6494 " When shutting down, execute action immediately\n"
6495 " --preset-mode= Apply only enable, only disable, or all presets\n"
6496 " --root=PATH Enable unit files in the specified root directory\n"
6497 " -n --lines=INTEGER Number of journal entries to show\n"
6498 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6499 " short-precise, short-monotonic, verbose,\n"
6500 " export, json, json-pretty, json-sse, cat)\n"
6501 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6502 " --plain Print unit dependencies as a list instead of a tree\n\n"
6504 " list-units [PATTERN...] List loaded units\n"
6505 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6506 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6507 " start NAME... Start (activate) one or more units\n"
6508 " stop NAME... Stop (deactivate) one or more units\n"
6509 " reload NAME... Reload one or more units\n"
6510 " restart NAME... Start or restart one or more units\n"
6511 " try-restart NAME... Restart one or more units if active\n"
6512 " reload-or-restart NAME... Reload one or more units if possible,\n"
6513 " otherwise start or restart\n"
6514 " try-reload-or-restart NAME... If active, reload one or more units,\n"
6515 " if supported, otherwise restart\n"
6516 " isolate NAME Start one unit and stop all others\n"
6517 " kill NAME... Send signal to processes of a unit\n"
6518 " is-active PATTERN... Check whether units are active\n"
6519 " is-failed PATTERN... Check whether units are failed\n"
6520 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6521 " show [PATTERN...|JOB...] Show properties of one or more\n"
6522 " units/jobs or the manager\n"
6523 " cat PATTERN... Show files and drop-ins of one or more units\n"
6524 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6525 " help PATTERN...|PID... Show manual for one or more units\n"
6526 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6528 " list-dependencies [NAME] Recursively show units which are required\n"
6529 " or wanted by this unit or by which this\n"
6530 " unit is required or wanted\n\n"
6531 "Unit File Commands:\n"
6532 " list-unit-files [PATTERN...] List installed unit files\n"
6533 " enable NAME... Enable one or more unit files\n"
6534 " disable NAME... Disable one or more unit files\n"
6535 " reenable NAME... Reenable one or more unit files\n"
6536 " preset NAME... Enable/disable one or more unit files\n"
6537 " based on preset configuration\n"
6538 " preset-all Enable/disable all unit files based on\n"
6539 " preset configuration\n"
6540 " is-enabled NAME... Check whether unit files are enabled\n"
6541 " mask NAME... Mask one or more units\n"
6542 " unmask NAME... Unmask one or more units\n"
6543 " link PATH... Link one or more units files into\n"
6544 " the search path\n"
6545 " revert NAME... Revert one or more unit files to vendor\n"
6547 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6548 " on specified one or more units\n"
6549 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6550 " on specified one or more units\n"
6551 " edit NAME... Edit one or more unit files\n"
6552 " get-default Get the name of the default target\n"
6553 " set-default NAME Set the default target\n\n"
6554 "Machine Commands:\n"
6555 " list-machines [PATTERN...] List local containers and host\n\n"
6557 " list-jobs [PATTERN...] List jobs\n"
6558 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6559 "Environment Commands:\n"
6560 " show-environment Dump environment\n"
6561 " set-environment NAME=VALUE... Set one or more environment variables\n"
6562 " unset-environment NAME... Unset one or more environment variables\n"
6563 " import-environment [NAME...] Import all or some environment variables\n\n"
6564 "Manager Lifecycle Commands:\n"
6565 " daemon-reload Reload systemd manager configuration\n"
6566 " daemon-reexec Reexecute systemd manager\n\n"
6567 "System Commands:\n"
6568 " is-system-running Check whether system is fully running\n"
6569 " default Enter system default mode\n"
6570 " rescue Enter system rescue mode\n"
6571 " emergency Enter system emergency mode\n"
6572 " halt Shut down and halt the system\n"
6573 " poweroff Shut down and power-off the system\n"
6574 " reboot [ARG] Shut down and reboot the system\n"
6575 " kexec Shut down and reboot the system with kexec\n"
6576 " exit [EXIT_CODE] Request user instance or container exit\n"
6577 " switch-root ROOT [INIT] Change to a different root file system\n"
6578 " suspend Suspend the system\n"
6579 " hibernate Hibernate the system\n"
6580 " hybrid-sleep Hibernate and suspend the system\n",
6581 program_invocation_short_name
);
6584 static void halt_help(void) {
6585 printf("%s [OPTIONS...]%s\n\n"
6586 "%s the system.\n\n"
6587 " --help Show this help\n"
6588 " --halt Halt the machine\n"
6589 " -p --poweroff Switch off the machine\n"
6590 " --reboot Reboot the machine\n"
6591 " -f --force Force immediate halt/power-off/reboot\n"
6592 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6593 " -d --no-wtmp Don't write wtmp record\n"
6594 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6595 program_invocation_short_name
,
6596 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6597 arg_action
== ACTION_REBOOT
? "Reboot" :
6598 arg_action
== ACTION_POWEROFF
? "Power off" :
6602 static void shutdown_help(void) {
6603 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6604 "Shut down the system.\n\n"
6605 " --help Show this help\n"
6606 " -H --halt Halt the machine\n"
6607 " -P --poweroff Power-off the machine\n"
6608 " -r --reboot Reboot the machine\n"
6609 " -h Equivalent to --poweroff, overridden by --halt\n"
6610 " -k Don't halt/power-off/reboot, just send warnings\n"
6611 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6612 " -c Cancel a pending shutdown\n",
6613 program_invocation_short_name
);
6616 static void telinit_help(void) {
6617 printf("%s [OPTIONS...] {COMMAND}\n\n"
6618 "Send control commands to the init daemon.\n\n"
6619 " --help Show this help\n"
6620 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6622 " 0 Power-off the machine\n"
6623 " 6 Reboot the machine\n"
6624 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6625 " 1, s, S Enter rescue mode\n"
6626 " q, Q Reload init daemon configuration\n"
6627 " u, U Reexecute init daemon\n",
6628 program_invocation_short_name
);
6631 static void runlevel_help(void) {
6632 printf("%s [OPTIONS...]\n\n"
6633 "Prints the previous and current runlevel of the init system.\n\n"
6634 " --help Show this help\n",
6635 program_invocation_short_name
);
6638 static void help_types(void) {
6642 puts("Available unit types:");
6643 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6644 puts(unit_type_to_string(i
));
6647 static void help_states(void) {
6651 puts("Available unit load states:");
6652 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6653 puts(unit_load_state_to_string(i
));
6656 puts("\nAvailable unit active states:");
6657 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6658 puts(unit_active_state_to_string(i
));
6661 puts("\nAvailable automount unit substates:");
6662 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6663 puts(automount_state_to_string(i
));
6666 puts("\nAvailable busname unit substates:");
6667 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6668 puts(busname_state_to_string(i
));
6671 puts("\nAvailable device unit substates:");
6672 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6673 puts(device_state_to_string(i
));
6676 puts("\nAvailable mount unit substates:");
6677 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6678 puts(mount_state_to_string(i
));
6681 puts("\nAvailable path unit substates:");
6682 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6683 puts(path_state_to_string(i
));
6686 puts("\nAvailable scope unit substates:");
6687 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6688 puts(scope_state_to_string(i
));
6691 puts("\nAvailable service unit substates:");
6692 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6693 puts(service_state_to_string(i
));
6696 puts("\nAvailable slice unit substates:");
6697 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6698 puts(slice_state_to_string(i
));
6701 puts("\nAvailable socket unit substates:");
6702 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6703 puts(socket_state_to_string(i
));
6706 puts("\nAvailable swap unit substates:");
6707 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6708 puts(swap_state_to_string(i
));
6711 puts("\nAvailable target unit substates:");
6712 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6713 puts(target_state_to_string(i
));
6716 puts("\nAvailable timer unit substates:");
6717 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6718 puts(timer_state_to_string(i
));
6721 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6730 ARG_IGNORE_DEPENDENCIES
,
6743 ARG_NO_ASK_PASSWORD
,
6756 static const struct option options
[] = {
6757 { "help", no_argument
, NULL
, 'h' },
6758 { "version", no_argument
, NULL
, ARG_VERSION
},
6759 { "type", required_argument
, NULL
, 't' },
6760 { "property", required_argument
, NULL
, 'p' },
6761 { "all", no_argument
, NULL
, 'a' },
6762 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6763 { "after", no_argument
, NULL
, ARG_AFTER
},
6764 { "before", no_argument
, NULL
, ARG_BEFORE
},
6765 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6766 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6767 { "full", no_argument
, NULL
, 'l' },
6768 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6769 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6770 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6771 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6772 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6773 { "value", no_argument
, NULL
, ARG_VALUE
},
6774 { "user", no_argument
, NULL
, ARG_USER
},
6775 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6776 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6777 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6778 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6779 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6780 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6781 { "quiet", no_argument
, NULL
, 'q' },
6782 { "root", required_argument
, NULL
, ARG_ROOT
},
6783 { "force", no_argument
, NULL
, ARG_FORCE
},
6784 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6785 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6786 { "signal", required_argument
, NULL
, 's' },
6787 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6788 { "host", required_argument
, NULL
, 'H' },
6789 { "machine", required_argument
, NULL
, 'M' },
6790 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6791 { "lines", required_argument
, NULL
, 'n' },
6792 { "output", required_argument
, NULL
, 'o' },
6793 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6794 { "state", required_argument
, NULL
, ARG_STATE
},
6795 { "recursive", no_argument
, NULL
, 'r' },
6796 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6797 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6798 { "now", no_argument
, NULL
, ARG_NOW
},
6799 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6809 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6810 arg_ask_password
= true;
6812 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6824 if (isempty(optarg
)) {
6825 log_error("--type requires arguments.");
6831 _cleanup_free_
char *type
= NULL
;
6833 r
= extract_first_word(&p
, &type
, ",", 0);
6835 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6840 if (streq(type
, "help")) {
6845 if (unit_type_from_string(type
) >= 0) {
6846 if (strv_push(&arg_types
, type
) < 0)
6852 /* It's much nicer to use --state= for
6853 * load states, but let's support this
6854 * in --types= too for compatibility
6855 * with old versions */
6856 if (unit_load_state_from_string(type
) >= 0) {
6857 if (strv_push(&arg_states
, type
) < 0)
6863 log_error("Unknown unit type or load state '%s'.", type
);
6864 log_info("Use -t help to see a list of allowed values.");
6872 /* Make sure that if the empty property list
6873 was specified, we won't show any properties. */
6874 if (isempty(optarg
) && !arg_properties
) {
6875 arg_properties
= new0(char*, 1);
6876 if (!arg_properties
)
6881 _cleanup_free_
char *prop
= NULL
;
6883 r
= extract_first_word(&p
, &prop
, ",", 0);
6885 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6890 if (strv_push(&arg_properties
, prop
) < 0)
6897 /* If the user asked for a particular
6898 * property, show it to him, even if it is
6910 arg_dependency
= DEPENDENCY_REVERSE
;
6914 arg_dependency
= DEPENDENCY_AFTER
;
6918 arg_dependency
= DEPENDENCY_BEFORE
;
6921 case ARG_SHOW_TYPES
:
6922 arg_show_types
= true;
6930 arg_job_mode
= optarg
;
6934 arg_job_mode
= "fail";
6937 case ARG_IRREVERSIBLE
:
6938 arg_job_mode
= "replace-irreversibly";
6941 case ARG_IGNORE_DEPENDENCIES
:
6942 arg_job_mode
= "ignore-dependencies";
6946 arg_scope
= UNIT_FILE_USER
;
6950 arg_scope
= UNIT_FILE_SYSTEM
;
6954 arg_scope
= UNIT_FILE_GLOBAL
;
6958 arg_no_block
= true;
6962 arg_no_legend
= true;
6966 arg_no_pager
= true;
6974 r
= parse_path_argument_and_warn(optarg
, false, &arg_root
);
6984 if (strv_extend(&arg_states
, "failed") < 0)
7002 arg_no_reload
= true;
7006 arg_kill_who
= optarg
;
7010 arg_signal
= signal_from_string_try_harder(optarg
);
7011 if (arg_signal
< 0) {
7012 log_error("Failed to parse signal string %s.", optarg
);
7017 case ARG_NO_ASK_PASSWORD
:
7018 arg_ask_password
= false;
7022 arg_transport
= BUS_TRANSPORT_REMOTE
;
7027 arg_transport
= BUS_TRANSPORT_MACHINE
;
7036 if (safe_atou(optarg
, &arg_lines
) < 0) {
7037 log_error("Failed to parse lines '%s'", optarg
);
7043 arg_output
= output_mode_from_string(optarg
);
7044 if (arg_output
< 0) {
7045 log_error("Unknown output '%s'.", optarg
);
7051 arg_ignore_inhibitors
= true;
7058 case ARG_FIRMWARE_SETUP
:
7059 arg_firmware_setup
= true;
7063 if (isempty(optarg
)) {
7064 log_error("--signal requires arguments.");
7070 _cleanup_free_
char *s
= NULL
;
7072 r
= extract_first_word(&p
, &s
, ",", 0);
7074 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
7079 if (streq(s
, "help")) {
7084 if (strv_push(&arg_states
, s
) < 0)
7093 if (geteuid() != 0) {
7094 log_error("--recursive requires root privileges.");
7098 arg_recursive
= true;
7101 case ARG_PRESET_MODE
:
7103 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
7104 if (arg_preset_mode
< 0) {
7105 log_error("Failed to parse preset mode: %s.", optarg
);
7116 if (strv_extend(&arg_wall
, optarg
) < 0)
7124 assert_not_reached("Unhandled option");
7127 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
7128 log_error("Cannot access user instance remotely.");
7135 static int halt_parse_argv(int argc
, char *argv
[]) {
7144 static const struct option options
[] = {
7145 { "help", no_argument
, NULL
, ARG_HELP
},
7146 { "halt", no_argument
, NULL
, ARG_HALT
},
7147 { "poweroff", no_argument
, NULL
, 'p' },
7148 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
7149 { "force", no_argument
, NULL
, 'f' },
7150 { "wtmp-only", no_argument
, NULL
, 'w' },
7151 { "no-wtmp", no_argument
, NULL
, 'd' },
7152 { "no-sync", no_argument
, NULL
, 'n' },
7153 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7162 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
7163 if (runlevel
== '0' || runlevel
== '6')
7166 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
7174 arg_action
= ACTION_HALT
;
7178 if (arg_action
!= ACTION_REBOOT
)
7179 arg_action
= ACTION_POWEROFF
;
7183 arg_action
= ACTION_REBOOT
;
7208 /* Compatibility nops */
7215 assert_not_reached("Unhandled option");
7218 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7219 r
= update_reboot_parameter_and_warn(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7222 } else if (optind
< argc
) {
7223 log_error("Too many arguments.");
7230 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7234 if (streq(t
, "now"))
7236 else if (!strchr(t
, ':')) {
7239 if (safe_atou64(t
, &u
) < 0)
7242 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7251 hour
= strtol(t
, &e
, 10);
7252 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7255 minute
= strtol(e
+1, &e
, 10);
7256 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7259 n
= now(CLOCK_REALTIME
);
7260 s
= (time_t) (n
/ USEC_PER_SEC
);
7262 assert_se(localtime_r(&s
, &tm
));
7264 tm
.tm_hour
= (int) hour
;
7265 tm
.tm_min
= (int) minute
;
7268 assert_se(s
= mktime(&tm
));
7270 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7273 *_u
+= USEC_PER_DAY
;
7279 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7286 static const struct option options
[] = {
7287 { "help", no_argument
, NULL
, ARG_HELP
},
7288 { "halt", no_argument
, NULL
, 'H' },
7289 { "poweroff", no_argument
, NULL
, 'P' },
7290 { "reboot", no_argument
, NULL
, 'r' },
7291 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7292 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7302 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7310 arg_action
= ACTION_HALT
;
7314 arg_action
= ACTION_POWEROFF
;
7319 arg_action
= ACTION_KEXEC
;
7321 arg_action
= ACTION_REBOOT
;
7325 arg_action
= ACTION_KEXEC
;
7329 if (arg_action
!= ACTION_HALT
)
7330 arg_action
= ACTION_POWEROFF
;
7345 /* Compatibility nops */
7349 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7356 assert_not_reached("Unhandled option");
7359 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7360 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7362 log_error("Failed to parse time specification: %s", argv
[optind
]);
7366 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7368 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7369 /* No time argument for shutdown cancel */
7370 wall
= argv
+ optind
;
7371 else if (argc
> optind
+ 1)
7372 /* We skip the time argument */
7373 wall
= argv
+ optind
+ 1;
7376 arg_wall
= strv_copy(wall
);
7386 static int telinit_parse_argv(int argc
, char *argv
[]) {
7393 static const struct option options
[] = {
7394 { "help", no_argument
, NULL
, ARG_HELP
},
7395 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7399 static const struct {
7403 { '0', ACTION_POWEROFF
},
7404 { '6', ACTION_REBOOT
},
7405 { '1', ACTION_RESCUE
},
7406 { '2', ACTION_RUNLEVEL2
},
7407 { '3', ACTION_RUNLEVEL3
},
7408 { '4', ACTION_RUNLEVEL4
},
7409 { '5', ACTION_RUNLEVEL5
},
7410 { 's', ACTION_RESCUE
},
7411 { 'S', ACTION_RESCUE
},
7412 { 'q', ACTION_RELOAD
},
7413 { 'Q', ACTION_RELOAD
},
7414 { 'u', ACTION_REEXEC
},
7415 { 'U', ACTION_REEXEC
}
7424 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7439 assert_not_reached("Unhandled option");
7442 if (optind
>= argc
) {
7443 log_error("%s: required argument missing.", program_invocation_short_name
);
7447 if (optind
+ 1 < argc
) {
7448 log_error("Too many arguments.");
7452 if (strlen(argv
[optind
]) != 1) {
7453 log_error("Expected single character argument.");
7457 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7458 if (table
[i
].from
== argv
[optind
][0])
7461 if (i
>= ELEMENTSOF(table
)) {
7462 log_error("Unknown command '%s'.", argv
[optind
]);
7466 arg_action
= table
[i
].to
;
7473 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7479 static const struct option options
[] = {
7480 { "help", no_argument
, NULL
, ARG_HELP
},
7489 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7500 assert_not_reached("Unhandled option");
7503 if (optind
< argc
) {
7504 log_error("Too many arguments.");
7511 static int parse_argv(int argc
, char *argv
[]) {
7515 if (program_invocation_short_name
) {
7517 if (strstr(program_invocation_short_name
, "halt")) {
7518 arg_action
= ACTION_HALT
;
7519 return halt_parse_argv(argc
, argv
);
7520 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7521 arg_action
= ACTION_POWEROFF
;
7522 return halt_parse_argv(argc
, argv
);
7523 } else if (strstr(program_invocation_short_name
, "reboot")) {
7525 arg_action
= ACTION_KEXEC
;
7527 arg_action
= ACTION_REBOOT
;
7528 return halt_parse_argv(argc
, argv
);
7529 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7530 arg_action
= ACTION_POWEROFF
;
7531 return shutdown_parse_argv(argc
, argv
);
7532 } else if (strstr(program_invocation_short_name
, "init")) {
7534 if (sd_booted() > 0) {
7535 arg_action
= _ACTION_INVALID
;
7536 return telinit_parse_argv(argc
, argv
);
7538 /* Hmm, so some other init system is
7539 * running, we need to forward this
7540 * request to it. For now we simply
7541 * guess that it is Upstart. */
7543 execv(TELINIT
, argv
);
7545 log_error("Couldn't find an alternative telinit implementation to spawn.");
7549 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7550 arg_action
= ACTION_RUNLEVEL
;
7551 return runlevel_parse_argv(argc
, argv
);
7555 arg_action
= ACTION_SYSTEMCTL
;
7556 return systemctl_parse_argv(argc
, argv
);
7559 #ifdef HAVE_SYSV_COMPAT
7560 _pure_
static int action_to_runlevel(void) {
7562 static const char table
[_ACTION_MAX
] = {
7563 [ACTION_HALT
] = '0',
7564 [ACTION_POWEROFF
] = '0',
7565 [ACTION_REBOOT
] = '6',
7566 [ACTION_RUNLEVEL2
] = '2',
7567 [ACTION_RUNLEVEL3
] = '3',
7568 [ACTION_RUNLEVEL4
] = '4',
7569 [ACTION_RUNLEVEL5
] = '5',
7570 [ACTION_RESCUE
] = '1'
7573 assert(arg_action
< _ACTION_MAX
);
7575 return table
[arg_action
];
7579 static int talk_initctl(void) {
7580 #ifdef HAVE_SYSV_COMPAT
7581 struct init_request request
= {
7582 .magic
= INIT_MAGIC
,
7584 .cmd
= INIT_CMD_RUNLVL
7587 _cleanup_close_
int fd
= -1;
7591 rl
= action_to_runlevel();
7595 request
.runlevel
= rl
;
7597 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7599 if (errno
== ENOENT
)
7602 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7605 r
= loop_write(fd
, &request
, sizeof(request
), false);
7607 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7615 static int systemctl_main(int argc
, char *argv
[]) {
7617 static const Verb verbs
[] = {
7618 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
|VERB_NOCHROOT
, list_units
},
7619 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7620 { "list-sockets", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_sockets
},
7621 { "list-timers", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_timers
},
7622 { "list-jobs", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_jobs
},
7623 { "list-machines", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, list_machines
},
7624 { "clear-jobs", VERB_ANY
, 1, VERB_NOCHROOT
, trivial_method
},
7625 { "cancel", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, cancel_job
},
7626 { "start", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7627 { "stop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7628 { "condstop", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7629 { "reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7630 { "restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7631 { "try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7632 { "reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7633 { "reload-or-try-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatbility with old systemctl <= 228 */
7634 { "try-reload-or-restart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
},
7635 { "force-reload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with SysV */
7636 { "condreload", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with ALTLinux */
7637 { "condrestart", 2, VERB_ANY
, VERB_NOCHROOT
, start_unit
}, /* For compatibility with RH */
7638 { "isolate", 2, 2, VERB_NOCHROOT
, start_unit
},
7639 { "kill", 2, VERB_ANY
, VERB_NOCHROOT
, kill_unit
},
7640 { "is-active", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7641 { "check", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_active
},
7642 { "is-failed", 2, VERB_ANY
, VERB_NOCHROOT
, check_unit_failed
},
7643 { "show", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7644 { "cat", 2, VERB_ANY
, VERB_NOCHROOT
, cat
},
7645 { "status", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7646 { "help", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, show
},
7647 { "daemon-reload", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7648 { "daemon-reexec", VERB_ANY
, 1, VERB_NOCHROOT
, daemon_reload
},
7649 { "show-environment", VERB_ANY
, 1, VERB_NOCHROOT
, show_environment
},
7650 { "set-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7651 { "unset-environment", 2, VERB_ANY
, VERB_NOCHROOT
, set_environment
},
7652 { "import-environment", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, import_environment
},
7653 { "halt", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7654 { "poweroff", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7655 { "reboot", VERB_ANY
, 2, VERB_NOCHROOT
, start_system_special
},
7656 { "kexec", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7657 { "suspend", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7658 { "hibernate", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7659 { "hybrid-sleep", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7660 { "default", VERB_ANY
, 1, VERB_NOCHROOT
, start_special
},
7661 { "rescue", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7662 { "emergency", VERB_ANY
, 1, VERB_NOCHROOT
, start_system_special
},
7663 { "exit", VERB_ANY
, 2, VERB_NOCHROOT
, start_special
},
7664 { "reset-failed", VERB_ANY
, VERB_ANY
, VERB_NOCHROOT
, reset_failed
},
7665 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7666 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7667 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7668 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7669 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7670 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7671 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7672 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7673 { "link", 2, VERB_ANY
, 0, enable_unit
},
7674 { "revert", 2, VERB_ANY
, 0, enable_unit
},
7675 { "switch-root", 2, VERB_ANY
, VERB_NOCHROOT
, switch_root
},
7676 { "list-dependencies", VERB_ANY
, 2, VERB_NOCHROOT
, list_dependencies
},
7677 { "set-default", 2, 2, 0, set_default
},
7678 { "get-default", VERB_ANY
, 1, 0, get_default
},
7679 { "set-property", 3, VERB_ANY
, VERB_NOCHROOT
, set_property
},
7680 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7681 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7682 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7683 { "edit", 2, VERB_ANY
, VERB_NOCHROOT
, edit
},
7687 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7690 static int reload_with_fallback(void) {
7692 /* First, try systemd via D-Bus. */
7693 if (daemon_reload(0, NULL
, NULL
) >= 0)
7696 /* Nothing else worked, so let's try signals */
7697 assert(IN_SET(arg_action
, ACTION_RELOAD
, ACTION_REEXEC
));
7699 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7700 return log_error_errno(errno
, "kill() failed: %m");
7705 static int start_with_fallback(void) {
7707 /* First, try systemd via D-Bus. */
7708 if (start_unit(0, NULL
, NULL
) >= 0)
7711 /* Nothing else worked, so let's try /dev/initctl */
7712 if (talk_initctl() > 0)
7715 log_error("Failed to talk to init daemon.");
7719 static int halt_now(enum action a
) {
7722 /* The kernel will automaticall flush ATA disks and suchlike
7723 * on reboot(), but the file systems need to be synce'd
7724 * explicitly in advance. */
7728 /* Make sure C-A-D is handled by the kernel from this point
7730 (void) reboot(RB_ENABLE_CAD
);
7735 log_info("Halting.");
7736 (void) reboot(RB_HALT_SYSTEM
);
7739 case ACTION_POWEROFF
:
7740 log_info("Powering off.");
7741 (void) reboot(RB_POWER_OFF
);
7745 case ACTION_REBOOT
: {
7746 _cleanup_free_
char *param
= NULL
;
7748 r
= read_one_line_file("/run/systemd/reboot-param", ¶m
);
7750 log_warning_errno(r
, "Failed to read reboot parameter file: %m");
7752 if (!isempty(param
)) {
7753 log_info("Rebooting with argument '%s'.", param
);
7754 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7755 log_warning_errno(errno
, "Failed to reboot with parameter, retrying without: %m");
7758 log_info("Rebooting.");
7759 (void) reboot(RB_AUTOBOOT
);
7764 assert_not_reached("Unknown action.");
7768 static int logind_schedule_shutdown(void) {
7771 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7772 char date
[FORMAT_TIMESTAMP_MAX
];
7777 r
= acquire_bus(BUS_FULL
, &bus
);
7781 switch (arg_action
) {
7785 case ACTION_POWEROFF
:
7786 action
= "poweroff";
7801 action
= strjoina("dry-", action
);
7803 (void) logind_set_wall_message();
7805 r
= sd_bus_call_method(
7807 "org.freedesktop.login1",
7808 "/org/freedesktop/login1",
7809 "org.freedesktop.login1.Manager",
7817 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7819 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7822 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7827 static int halt_main(void) {
7830 r
= logind_check_inhibitors(arg_action
);
7835 return logind_schedule_shutdown();
7837 if (geteuid() != 0) {
7838 if (arg_dry
|| arg_force
> 0) {
7839 log_error("Must be root.");
7843 /* Try logind if we are a normal user and no special
7844 * mode applies. Maybe PolicyKit allows us to shutdown
7846 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7847 r
= logind_reboot(arg_action
);
7850 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7851 /* requested operation is not
7852 * supported on the local system or
7853 * already in progress */
7855 /* on all other errors, try low-level operation */
7859 if (!arg_dry
&& !arg_force
)
7860 return start_with_fallback();
7862 assert(geteuid() == 0);
7865 if (sd_booted() > 0)
7866 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7868 r
= utmp_put_shutdown();
7870 log_warning_errno(r
, "Failed to write utmp record: %m");
7877 r
= halt_now(arg_action
);
7878 return log_error_errno(r
, "Failed to reboot: %m");
7881 static int runlevel_main(void) {
7882 int r
, runlevel
, previous
;
7884 r
= utmp_get_runlevel(&runlevel
, &previous
);
7891 previous
<= 0 ? 'N' : previous
,
7892 runlevel
<= 0 ? 'N' : runlevel
);
7897 static int logind_cancel_shutdown(void) {
7899 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7903 r
= acquire_bus(BUS_FULL
, &bus
);
7907 (void) logind_set_wall_message();
7909 r
= sd_bus_call_method(
7911 "org.freedesktop.login1",
7912 "/org/freedesktop/login1",
7913 "org.freedesktop.login1.Manager",
7914 "CancelScheduledShutdown",
7918 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7922 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7927 int main(int argc
, char*argv
[]) {
7930 setlocale(LC_ALL
, "");
7931 log_parse_environment();
7935 /* Explicitly not on_tty() to avoid setting cached value.
7936 * This becomes relevant for piping output which might be
7938 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7940 r
= parse_argv(argc
, argv
);
7944 if (arg_action
!= ACTION_SYSTEMCTL
&& running_in_chroot() > 0) {
7945 log_info("Running in chroot, ignoring request.");
7950 /* systemctl_main() will print an error message for the bus
7951 * connection, but only if it needs to */
7953 switch (arg_action
) {
7955 case ACTION_SYSTEMCTL
:
7956 r
= systemctl_main(argc
, argv
);
7960 case ACTION_POWEROFF
:
7966 case ACTION_RUNLEVEL2
:
7967 case ACTION_RUNLEVEL3
:
7968 case ACTION_RUNLEVEL4
:
7969 case ACTION_RUNLEVEL5
:
7971 case ACTION_EMERGENCY
:
7972 case ACTION_DEFAULT
:
7973 r
= start_with_fallback();
7978 r
= reload_with_fallback();
7981 case ACTION_CANCEL_SHUTDOWN
:
7982 r
= logind_cancel_shutdown();
7985 case ACTION_RUNLEVEL
:
7986 r
= runlevel_main();
7989 case _ACTION_INVALID
:
7991 assert_not_reached("Unknown action");
7998 ask_password_agent_close();
7999 polkit_agent_close();
8001 strv_free(arg_types
);
8002 strv_free(arg_states
);
8003 strv_free(arg_properties
);
8005 strv_free(arg_wall
);
8008 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
8009 return r
< 0 ? EXIT_FAILURE
: r
;