1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include "selinux-access.h"
31 #include "clock-util.h"
32 #include "path-util.h"
34 #include "architecture.h"
38 #include "dbus-manager.h"
39 #include "dbus-unit.h"
40 #include "dbus-snapshot.h"
41 #include "dbus-execute.h"
42 #include "bus-common-errors.h"
43 #include "formats-util.h"
45 static int property_get_version(
48 const char *interface
,
50 sd_bus_message
*reply
,
52 sd_bus_error
*error
) {
57 return sd_bus_message_append(reply
, "s", PACKAGE_VERSION
);
60 static int property_get_features(
63 const char *interface
,
65 sd_bus_message
*reply
,
67 sd_bus_error
*error
) {
72 return sd_bus_message_append(reply
, "s", SYSTEMD_FEATURES
);
75 static int property_get_virtualization(
78 const char *interface
,
80 sd_bus_message
*reply
,
82 sd_bus_error
*error
) {
89 v
= detect_virtualization();
91 /* Make sure to return the empty string when we detect no virtualization, as that is the API.
93 * https://github.com/systemd/systemd/issues/1423
96 return sd_bus_message_append(
98 v
== VIRTUALIZATION_NONE
? "" : virtualization_to_string(v
));
101 static int property_get_architecture(
104 const char *interface
,
105 const char *property
,
106 sd_bus_message
*reply
,
108 sd_bus_error
*error
) {
113 return sd_bus_message_append(reply
, "s", architecture_to_string(uname_architecture()));
116 static int property_get_tainted(
119 const char *interface
,
120 const char *property
,
121 sd_bus_message
*reply
,
123 sd_bus_error
*error
) {
125 char buf
[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e
= buf
;
126 _cleanup_free_
char *p
= NULL
;
127 Manager
*m
= userdata
;
134 e
= stpcpy(e
, "split-usr:");
136 if (readlink_malloc("/etc/mtab", &p
) < 0)
137 e
= stpcpy(e
, "mtab-not-symlink:");
139 if (access("/proc/cgroups", F_OK
) < 0)
140 e
= stpcpy(e
, "cgroups-missing:");
142 if (clock_is_localtime() > 0)
143 e
= stpcpy(e
, "local-hwclock:");
145 /* remove the last ':' */
149 return sd_bus_message_append(reply
, "s", buf
);
152 static int property_get_log_target(
155 const char *interface
,
156 const char *property
,
157 sd_bus_message
*reply
,
159 sd_bus_error
*error
) {
164 return sd_bus_message_append(reply
, "s", log_target_to_string(log_get_target()));
167 static int property_set_log_target(
170 const char *interface
,
171 const char *property
,
172 sd_bus_message
*value
,
174 sd_bus_error
*error
) {
182 r
= sd_bus_message_read(value
, "s", &t
);
186 return log_set_target_from_string(t
);
189 static int property_get_log_level(
192 const char *interface
,
193 const char *property
,
194 sd_bus_message
*reply
,
196 sd_bus_error
*error
) {
198 _cleanup_free_
char *t
= NULL
;
204 r
= log_level_to_string_alloc(log_get_max_level(), &t
);
208 return sd_bus_message_append(reply
, "s", t
);
211 static int property_set_log_level(
214 const char *interface
,
215 const char *property
,
216 sd_bus_message
*value
,
218 sd_bus_error
*error
) {
226 r
= sd_bus_message_read(value
, "s", &t
);
230 return log_set_max_level_from_string(t
);
233 static int property_get_n_names(
236 const char *interface
,
237 const char *property
,
238 sd_bus_message
*reply
,
240 sd_bus_error
*error
) {
242 Manager
*m
= userdata
;
248 return sd_bus_message_append(reply
, "u", (uint32_t) hashmap_size(m
->units
));
251 static int property_get_n_failed_units(
254 const char *interface
,
255 const char *property
,
256 sd_bus_message
*reply
,
258 sd_bus_error
*error
) {
260 Manager
*m
= userdata
;
266 return sd_bus_message_append(reply
, "u", (uint32_t) set_size(m
->failed_units
));
269 static int property_get_n_jobs(
272 const char *interface
,
273 const char *property
,
274 sd_bus_message
*reply
,
276 sd_bus_error
*error
) {
278 Manager
*m
= userdata
;
284 return sd_bus_message_append(reply
, "u", (uint32_t) hashmap_size(m
->jobs
));
287 static int property_get_progress(
290 const char *interface
,
291 const char *property
,
292 sd_bus_message
*reply
,
294 sd_bus_error
*error
) {
296 Manager
*m
= userdata
;
303 if (dual_timestamp_is_set(&m
->finish_timestamp
))
306 d
= 1.0 - ((double) hashmap_size(m
->jobs
) / (double) m
->n_installed_jobs
);
308 return sd_bus_message_append(reply
, "d", d
);
311 static int property_get_system_state(
314 const char *interface
,
315 const char *property
,
316 sd_bus_message
*reply
,
318 sd_bus_error
*error
) {
320 Manager
*m
= userdata
;
326 return sd_bus_message_append(reply
, "s", manager_state_to_string(manager_state(m
)));
329 static int property_set_runtime_watchdog(
332 const char *interface
,
333 const char *property
,
334 sd_bus_message
*value
,
336 sd_bus_error
*error
) {
338 usec_t
*t
= userdata
;
344 assert_cc(sizeof(usec_t
) == sizeof(uint64_t));
346 r
= sd_bus_message_read(value
, "t", t
);
350 return watchdog_set_timeout(t
);
353 static int method_get_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
354 _cleanup_free_
char *path
= NULL
;
355 Manager
*m
= userdata
;
363 /* Anyone can call this method */
365 r
= sd_bus_message_read(message
, "s", &name
);
370 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
373 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
377 r
= sd_bus_creds_get_pid(creds
, &pid
);
381 u
= manager_get_unit_by_pid(m
, pid
);
383 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Client not member of any unit.");
385 u
= manager_get_unit(m
, name
);
387 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s not loaded.", name
);
390 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
394 path
= unit_dbus_path(u
);
398 return sd_bus_reply_method_return(message
, "o", path
);
401 static int method_get_unit_by_pid(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
402 _cleanup_free_
char *path
= NULL
;
403 Manager
*m
= userdata
;
411 assert_cc(sizeof(pid_t
) == sizeof(uint32_t));
413 /* Anyone can call this method */
415 r
= sd_bus_message_read(message
, "u", &pid
);
419 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid PID " PID_FMT
, pid
);
422 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
424 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
428 r
= sd_bus_creds_get_pid(creds
, &pid
);
433 u
= manager_get_unit_by_pid(m
, pid
);
435 return sd_bus_error_setf(error
, BUS_ERROR_NO_UNIT_FOR_PID
, "PID "PID_FMT
" does not belong to any loaded unit.", pid
);
437 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
441 path
= unit_dbus_path(u
);
445 return sd_bus_reply_method_return(message
, "o", path
);
448 static int method_load_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
449 _cleanup_free_
char *path
= NULL
;
450 Manager
*m
= userdata
;
458 /* Anyone can call this method */
460 r
= sd_bus_message_read(message
, "s", &name
);
465 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
468 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
472 r
= sd_bus_creds_get_pid(creds
, &pid
);
476 u
= manager_get_unit_by_pid(m
, pid
);
478 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Client not member of any unit.");
480 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
485 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
489 path
= unit_dbus_path(u
);
493 return sd_bus_reply_method_return(message
, "o", path
);
496 static int method_start_unit_generic(sd_bus_message
*message
, Manager
*m
, JobType job_type
, bool reload_if_possible
, sd_bus_error
*error
) {
504 r
= sd_bus_message_read(message
, "s", &name
);
508 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
512 return bus_unit_method_start_generic(message
, u
, job_type
, reload_if_possible
, error
);
515 static int method_start_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
516 return method_start_unit_generic(message
, userdata
, JOB_START
, false, error
);
519 static int method_stop_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
520 return method_start_unit_generic(message
, userdata
, JOB_STOP
, false, error
);
523 static int method_reload_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
524 return method_start_unit_generic(message
, userdata
, JOB_RELOAD
, false, error
);
527 static int method_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
528 return method_start_unit_generic(message
, userdata
, JOB_RESTART
, false, error
);
531 static int method_try_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
532 return method_start_unit_generic(message
, userdata
, JOB_TRY_RESTART
, false, error
);
535 static int method_reload_or_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
536 return method_start_unit_generic(message
, userdata
, JOB_RESTART
, true, error
);
539 static int method_reload_or_try_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
540 return method_start_unit_generic(message
, userdata
, JOB_TRY_RESTART
, true, error
);
543 static int method_start_unit_replace(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
544 Manager
*m
= userdata
;
545 const char *old_name
;
552 r
= sd_bus_message_read(message
, "s", &old_name
);
556 u
= manager_get_unit(m
, old_name
);
557 if (!u
|| !u
->job
|| u
->job
->type
!= JOB_START
)
558 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "No job queued for unit %s", old_name
);
560 return method_start_unit_generic(message
, m
, JOB_START
, false, error
);
563 static int method_kill_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
564 Manager
*m
= userdata
;
572 r
= sd_bus_message_read(message
, "s", &name
);
576 u
= manager_get_unit(m
, name
);
578 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
580 return bus_unit_method_kill(message
, u
, error
);
583 static int method_reset_failed_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
584 Manager
*m
= userdata
;
592 r
= sd_bus_message_read(message
, "s", &name
);
596 u
= manager_get_unit(m
, name
);
598 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
600 return bus_unit_method_reset_failed(message
, u
, error
);
603 static int method_set_unit_properties(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
604 Manager
*m
= userdata
;
612 r
= sd_bus_message_read(message
, "s", &name
);
616 u
= manager_get_unit(m
, name
);
618 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
620 return bus_unit_method_set_properties(message
, u
, error
);
623 static int transient_unit_from_message(
625 sd_bus_message
*message
,
628 sd_bus_error
*error
) {
637 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
641 if (u
->load_state
!= UNIT_NOT_FOUND
||
642 set_size(u
->dependencies
[UNIT_REFERENCED_BY
]) > 0)
643 return sd_bus_error_setf(error
, BUS_ERROR_UNIT_EXISTS
, "Unit %s already exists.", name
);
645 /* OK, the unit failed to load and is unreferenced, now let's
646 * fill in the transient data instead */
647 r
= unit_make_transient(u
);
651 /* Set our properties */
652 r
= bus_unit_set_properties(u
, message
, UNIT_RUNTIME
, false, error
);
661 static int transient_aux_units_from_message(
663 sd_bus_message
*message
,
664 sd_bus_error
*error
) {
673 r
= sd_bus_message_enter_container(message
, 'a', "(sa(sv))");
677 while ((r
= sd_bus_message_enter_container(message
, 'r', "sa(sv)")) > 0) {
678 r
= sd_bus_message_read(message
, "s", &name
);
682 r
= transient_unit_from_message(m
, message
, name
, &u
, error
);
683 if (r
< 0 && r
!= -EEXIST
)
692 r
= sd_bus_message_exit_container(message
);
699 r
= sd_bus_message_exit_container(message
);
706 static int method_start_transient_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
707 const char *name
, *smode
;
708 Manager
*m
= userdata
;
717 r
= mac_selinux_access_check(message
, "start", error
);
721 r
= sd_bus_message_read(message
, "ss", &name
, &smode
);
725 t
= unit_name_to_type(name
);
727 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid unit type.");
729 if (!unit_vtable
[t
]->can_transient
)
730 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unit type %s does not support transient units.", unit_type_to_string(t
));
732 mode
= job_mode_from_string(smode
);
734 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Job mode %s is invalid.", smode
);
736 r
= bus_verify_manage_units_async(m
, message
, error
);
740 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
742 r
= transient_unit_from_message(m
, message
, name
, &u
, error
);
746 r
= transient_aux_units_from_message(m
, message
, error
);
750 /* And load this stub fully */
755 manager_dispatch_load_queue(m
);
757 /* Finally, start it */
758 return bus_unit_queue_job(message
, u
, JOB_START
, mode
, false, error
);
761 static int method_get_job(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
762 _cleanup_free_
char *path
= NULL
;
763 Manager
*m
= userdata
;
771 /* Anyone can call this method */
773 r
= sd_bus_message_read(message
, "u", &id
);
777 j
= manager_get_job(m
, id
);
779 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "Job %u does not exist.", (unsigned) id
);
781 r
= mac_selinux_unit_access_check(j
->unit
, message
, "status", error
);
785 path
= job_dbus_path(j
);
789 return sd_bus_reply_method_return(message
, "o", path
);
792 static int method_cancel_job(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
793 Manager
*m
= userdata
;
801 r
= sd_bus_message_read(message
, "u", &id
);
805 j
= manager_get_job(m
, id
);
807 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "Job %u does not exist.", (unsigned) id
);
809 return bus_job_method_cancel(message
, j
, error
);
812 static int method_clear_jobs(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
813 Manager
*m
= userdata
;
819 r
= mac_selinux_access_check(message
, "reload", error
);
823 r
= bus_verify_manage_units_async(m
, message
, error
);
827 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
829 manager_clear_jobs(m
);
831 return sd_bus_reply_method_return(message
, NULL
);
834 static int method_reset_failed(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
835 Manager
*m
= userdata
;
841 r
= mac_selinux_access_check(message
, "reload", error
);
845 r
= bus_verify_manage_units_async(m
, message
, error
);
849 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
851 manager_reset_failed(m
);
853 return sd_bus_reply_method_return(message
, NULL
);
856 static int list_units_filtered(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
, char **states
) {
857 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
858 Manager
*m
= userdata
;
867 /* Anyone can call this method */
869 r
= mac_selinux_access_check(message
, "status", error
);
873 r
= sd_bus_message_new_method_return(message
, &reply
);
877 r
= sd_bus_message_open_container(reply
, 'a', "(ssssssouso)");
881 HASHMAP_FOREACH_KEY(u
, k
, m
->units
, i
) {
882 _cleanup_free_
char *unit_path
= NULL
, *job_path
= NULL
;
888 following
= unit_following(u
);
890 if (!strv_isempty(states
) &&
891 !strv_contains(states
, unit_load_state_to_string(u
->load_state
)) &&
892 !strv_contains(states
, unit_active_state_to_string(unit_active_state(u
))) &&
893 !strv_contains(states
, unit_sub_state_to_string(u
)))
896 unit_path
= unit_dbus_path(u
);
901 job_path
= job_dbus_path(u
->job
);
906 r
= sd_bus_message_append(
907 reply
, "(ssssssouso)",
910 unit_load_state_to_string(u
->load_state
),
911 unit_active_state_to_string(unit_active_state(u
)),
912 unit_sub_state_to_string(u
),
913 following
? following
->id
: "",
915 u
->job
? u
->job
->id
: 0,
916 u
->job
? job_type_to_string(u
->job
->type
) : "",
917 job_path
? job_path
: "/");
922 r
= sd_bus_message_close_container(reply
);
926 return sd_bus_send(NULL
, reply
, NULL
);
929 static int method_list_units(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
930 return list_units_filtered(message
, userdata
, error
, NULL
);
933 static int method_list_units_filtered(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
934 _cleanup_strv_free_
char **states
= NULL
;
937 r
= sd_bus_message_read_strv(message
, &states
);
941 return list_units_filtered(message
, userdata
, error
, states
);
944 static int method_list_jobs(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
945 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
946 Manager
*m
= userdata
;
954 /* Anyone can call this method */
956 r
= mac_selinux_access_check(message
, "status", error
);
960 r
= sd_bus_message_new_method_return(message
, &reply
);
964 r
= sd_bus_message_open_container(reply
, 'a', "(usssoo)");
968 HASHMAP_FOREACH(j
, m
->jobs
, i
) {
969 _cleanup_free_
char *unit_path
= NULL
, *job_path
= NULL
;
971 job_path
= job_dbus_path(j
);
975 unit_path
= unit_dbus_path(j
->unit
);
979 r
= sd_bus_message_append(
983 job_type_to_string(j
->type
),
984 job_state_to_string(j
->state
),
991 r
= sd_bus_message_close_container(reply
);
995 return sd_bus_send(NULL
, reply
, NULL
);
998 static int method_subscribe(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
999 Manager
*m
= userdata
;
1005 /* Anyone can call this method */
1007 r
= mac_selinux_access_check(message
, "status", error
);
1011 if (sd_bus_message_get_bus(message
) == m
->api_bus
) {
1013 /* Note that direct bus connection subscribe by
1014 * default, we only track peers on the API bus here */
1016 if (!m
->subscribed
) {
1017 r
= sd_bus_track_new(sd_bus_message_get_bus(message
), &m
->subscribed
, NULL
, NULL
);
1022 r
= sd_bus_track_add_sender(m
->subscribed
, message
);
1026 return sd_bus_error_setf(error
, BUS_ERROR_ALREADY_SUBSCRIBED
, "Client is already subscribed.");
1029 return sd_bus_reply_method_return(message
, NULL
);
1032 static int method_unsubscribe(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1033 Manager
*m
= userdata
;
1039 /* Anyone can call this method */
1041 r
= mac_selinux_access_check(message
, "status", error
);
1045 if (sd_bus_message_get_bus(message
) == m
->api_bus
) {
1046 r
= sd_bus_track_remove_sender(m
->subscribed
, message
);
1050 return sd_bus_error_setf(error
, BUS_ERROR_NOT_SUBSCRIBED
, "Client is not subscribed.");
1053 return sd_bus_reply_method_return(message
, NULL
);
1056 static int method_dump(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1057 _cleanup_free_
char *dump
= NULL
;
1058 _cleanup_fclose_
FILE *f
= NULL
;
1059 Manager
*m
= userdata
;
1066 /* Anyone can call this method */
1068 r
= mac_selinux_access_check(message
, "status", error
);
1072 f
= open_memstream(&dump
, &size
);
1076 manager_dump_units(m
, f
, NULL
);
1077 manager_dump_jobs(m
, f
, NULL
);
1079 r
= fflush_and_check(f
);
1083 return sd_bus_reply_method_return(message
, "s", dump
);
1086 static int method_create_snapshot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1087 _cleanup_free_
char *path
= NULL
;
1088 Manager
*m
= userdata
;
1097 r
= mac_selinux_access_check(message
, "start", error
);
1101 r
= sd_bus_message_read(message
, "sb", &name
, &cleanup
);
1108 r
= bus_verify_manage_units_async(m
, message
, error
);
1112 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1114 r
= snapshot_create(m
, name
, cleanup
, error
, &s
);
1118 path
= unit_dbus_path(UNIT(s
));
1122 return sd_bus_reply_method_return(message
, "o", path
);
1125 static int method_remove_snapshot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1126 Manager
*m
= userdata
;
1134 r
= sd_bus_message_read(message
, "s", &name
);
1138 u
= manager_get_unit(m
, name
);
1140 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s does not exist.", name
);
1142 if (u
->type
!= UNIT_SNAPSHOT
)
1143 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not a snapshot", name
);
1145 return bus_snapshot_method_remove(message
, u
, error
);
1148 static int method_reload(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1149 Manager
*m
= userdata
;
1155 r
= mac_selinux_access_check(message
, "reload", error
);
1159 r
= bus_verify_reload_daemon_async(m
, message
, error
);
1163 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1165 /* Instead of sending the reply back right away, we just
1166 * remember that we need to and then send it after the reload
1167 * is finished. That way the caller knows when the reload
1170 assert(!m
->queued_message
);
1171 r
= sd_bus_message_new_method_return(message
, &m
->queued_message
);
1175 m
->exit_code
= MANAGER_RELOAD
;
1180 static int method_reexecute(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1181 Manager
*m
= userdata
;
1187 r
= mac_selinux_access_check(message
, "reload", error
);
1191 r
= bus_verify_reload_daemon_async(m
, message
, error
);
1195 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1197 /* We don't send a reply back here, the client should
1198 * just wait for us disconnecting. */
1200 m
->exit_code
= MANAGER_REEXECUTE
;
1204 static int method_exit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1205 Manager
*m
= userdata
;
1211 r
= mac_selinux_access_check(message
, "halt", error
);
1215 /* Exit() (in contrast to SetExitCode()) is actually allowed even if
1216 * we are running on the host. It will fall back on reboot() in
1217 * systemd-shutdown if it cannot do the exit() because it isn't a
1220 m
->exit_code
= MANAGER_EXIT
;
1222 return sd_bus_reply_method_return(message
, NULL
);
1225 static int method_reboot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1226 Manager
*m
= userdata
;
1232 r
= mac_selinux_access_check(message
, "reboot", error
);
1236 if (m
->running_as
!= MANAGER_SYSTEM
)
1237 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Reboot is only supported for system managers.");
1239 m
->exit_code
= MANAGER_REBOOT
;
1241 return sd_bus_reply_method_return(message
, NULL
);
1244 static int method_poweroff(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1245 Manager
*m
= userdata
;
1251 r
= mac_selinux_access_check(message
, "halt", error
);
1255 if (m
->running_as
!= MANAGER_SYSTEM
)
1256 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Powering off is only supported for system managers.");
1258 m
->exit_code
= MANAGER_POWEROFF
;
1260 return sd_bus_reply_method_return(message
, NULL
);
1263 static int method_halt(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1264 Manager
*m
= userdata
;
1270 r
= mac_selinux_access_check(message
, "halt", error
);
1274 if (m
->running_as
!= MANAGER_SYSTEM
)
1275 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Halt is only supported for system managers.");
1277 m
->exit_code
= MANAGER_HALT
;
1279 return sd_bus_reply_method_return(message
, NULL
);
1282 static int method_kexec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1283 Manager
*m
= userdata
;
1289 r
= mac_selinux_access_check(message
, "reboot", error
);
1293 if (m
->running_as
!= MANAGER_SYSTEM
)
1294 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "KExec is only supported for system managers.");
1296 m
->exit_code
= MANAGER_KEXEC
;
1298 return sd_bus_reply_method_return(message
, NULL
);
1301 static int method_switch_root(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1302 char *ri
= NULL
, *rt
= NULL
;
1303 const char *root
, *init
;
1304 Manager
*m
= userdata
;
1310 r
= mac_selinux_access_check(message
, "reboot", error
);
1314 if (m
->running_as
!= MANAGER_SYSTEM
)
1315 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Root switching is only supported by system manager.");
1317 r
= sd_bus_message_read(message
, "ss", &root
, &init
);
1321 if (path_equal(root
, "/") || !path_is_absolute(root
))
1322 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid switch root path %s", root
);
1325 if (isempty(init
)) {
1326 if (!path_is_os_tree(root
))
1327 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root
);
1329 _cleanup_free_
char *p
= NULL
;
1331 if (!path_is_absolute(init
))
1332 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid init path %s", init
);
1334 p
= strappend(root
, init
);
1338 if (access(p
, X_OK
) < 0)
1339 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified init binary %s does not exist.", p
);
1346 if (!isempty(init
)) {
1354 free(m
->switch_root
);
1355 m
->switch_root
= rt
;
1357 free(m
->switch_root_init
);
1358 m
->switch_root_init
= ri
;
1360 m
->exit_code
= MANAGER_SWITCH_ROOT
;
1362 return sd_bus_reply_method_return(message
, NULL
);
1365 static int method_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1366 _cleanup_strv_free_
char **plus
= NULL
;
1367 Manager
*m
= userdata
;
1373 r
= mac_selinux_access_check(message
, "reload", error
);
1377 r
= sd_bus_message_read_strv(message
, &plus
);
1380 if (!strv_env_is_valid(plus
))
1381 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1383 r
= bus_verify_set_environment_async(m
, message
, error
);
1387 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1389 r
= manager_environment_add(m
, NULL
, plus
);
1393 return sd_bus_reply_method_return(message
, NULL
);
1396 static int method_unset_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1397 _cleanup_strv_free_
char **minus
= NULL
;
1398 Manager
*m
= userdata
;
1404 r
= mac_selinux_access_check(message
, "reload", error
);
1408 r
= sd_bus_message_read_strv(message
, &minus
);
1412 if (!strv_env_name_or_assignment_is_valid(minus
))
1413 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1415 r
= bus_verify_set_environment_async(m
, message
, error
);
1419 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1421 r
= manager_environment_add(m
, minus
, NULL
);
1425 return sd_bus_reply_method_return(message
, NULL
);
1428 static int method_unset_and_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1429 _cleanup_strv_free_
char **minus
= NULL
, **plus
= NULL
;
1430 Manager
*m
= userdata
;
1436 r
= mac_selinux_access_check(message
, "reload", error
);
1440 r
= sd_bus_message_read_strv(message
, &minus
);
1444 r
= sd_bus_message_read_strv(message
, &plus
);
1448 if (!strv_env_name_or_assignment_is_valid(minus
))
1449 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1450 if (!strv_env_is_valid(plus
))
1451 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1453 r
= bus_verify_set_environment_async(m
, message
, error
);
1457 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1459 r
= manager_environment_add(m
, minus
, plus
);
1463 return sd_bus_reply_method_return(message
, NULL
);
1466 static int method_set_exit_code(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1468 Manager
*m
= userdata
;
1474 r
= mac_selinux_access_check(message
, "exit", error
);
1478 r
= sd_bus_message_read_basic(message
, 'y', &code
);
1482 if (m
->running_as
== MANAGER_SYSTEM
&& detect_container() <= 0)
1483 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "ExitCode can only be set for user service managers or in containers.");
1485 m
->return_value
= code
;
1487 return sd_bus_reply_method_return(message
, NULL
);
1490 static int method_list_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1491 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1492 Manager
*m
= userdata
;
1501 /* Anyone can call this method */
1503 r
= mac_selinux_access_check(message
, "status", error
);
1507 r
= sd_bus_message_new_method_return(message
, &reply
);
1511 h
= hashmap_new(&string_hash_ops
);
1515 r
= unit_file_get_list(m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
, NULL
, h
);
1519 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
1523 HASHMAP_FOREACH(item
, h
, i
) {
1525 r
= sd_bus_message_append(reply
, "(ss)", item
->path
, unit_file_state_to_string(item
->state
));
1530 unit_file_list_free(h
);
1532 r
= sd_bus_message_close_container(reply
);
1536 return sd_bus_send(NULL
, reply
, NULL
);
1539 unit_file_list_free(h
);
1543 static int method_get_unit_file_state(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1544 Manager
*m
= userdata
;
1546 UnitFileState state
;
1547 UnitFileScope scope
;
1553 /* Anyone can call this method */
1555 r
= mac_selinux_access_check(message
, "status", error
);
1559 r
= sd_bus_message_read(message
, "s", &name
);
1563 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1565 state
= unit_file_get_state(scope
, NULL
, name
);
1569 return sd_bus_reply_method_return(message
, "s", unit_file_state_to_string(state
));
1572 static int method_get_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1573 _cleanup_free_
char *default_target
= NULL
;
1574 Manager
*m
= userdata
;
1575 UnitFileScope scope
;
1581 /* Anyone can call this method */
1583 r
= mac_selinux_access_check(message
, "status", error
);
1587 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1589 r
= unit_file_get_default(scope
, NULL
, &default_target
);
1593 return sd_bus_reply_method_return(message
, "s", default_target
);
1596 static int send_unit_files_changed(sd_bus
*bus
, void *userdata
) {
1597 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
1602 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1606 return sd_bus_send(bus
, message
, NULL
);
1609 static int reply_unit_file_changes_and_free(
1611 sd_bus_message
*message
,
1612 int carries_install_info
,
1613 UnitFileChange
*changes
,
1614 unsigned n_changes
) {
1616 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1620 if (n_changes
> 0) {
1621 r
= bus_foreach_bus(m
, NULL
, send_unit_files_changed
, NULL
);
1623 log_debug_errno(r
, "Failed to send UnitFilesChanged signal: %m");
1626 r
= sd_bus_message_new_method_return(message
, &reply
);
1630 if (carries_install_info
>= 0) {
1631 r
= sd_bus_message_append(reply
, "b", carries_install_info
);
1636 r
= sd_bus_message_open_container(reply
, 'a', "(sss)");
1640 for (i
= 0; i
< n_changes
; i
++) {
1641 r
= sd_bus_message_append(
1643 unit_file_change_type_to_string(changes
[i
].type
),
1650 r
= sd_bus_message_close_container(reply
);
1654 return sd_bus_send(NULL
, reply
, NULL
);
1657 unit_file_changes_free(changes
, n_changes
);
1661 static int method_enable_unit_files_generic(
1662 sd_bus_message
*message
,
1665 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], bool force
, UnitFileChange
**changes
, unsigned *n_changes
),
1666 bool carries_install_info
,
1667 sd_bus_error
*error
) {
1669 _cleanup_strv_free_
char **l
= NULL
;
1670 UnitFileChange
*changes
= NULL
;
1671 unsigned n_changes
= 0;
1672 UnitFileScope scope
;
1673 int runtime
, force
, r
;
1678 r
= sd_bus_message_read_strv(message
, &l
);
1682 r
= sd_bus_message_read(message
, "bb", &runtime
, &force
);
1686 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1690 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1692 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1694 r
= call(scope
, runtime
, NULL
, l
, force
, &changes
, &n_changes
);
1698 return reply_unit_file_changes_and_free(m
, message
, carries_install_info
? r
: -1, changes
, n_changes
);
1701 static int method_enable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1702 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_enable
, true, error
);
1705 static int method_reenable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1706 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_reenable
, true, error
);
1709 static int method_link_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1710 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_link
, false, error
);
1713 static int unit_file_preset_without_mode(UnitFileScope scope
, bool runtime
, const char *root_dir
, char **files
, bool force
, UnitFileChange
**changes
, unsigned *n_changes
) {
1714 return unit_file_preset(scope
, runtime
, root_dir
, files
, UNIT_FILE_PRESET_FULL
, force
, changes
, n_changes
);
1717 static int method_preset_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1718 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_preset_without_mode
, true, error
);
1721 static int method_mask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1722 return method_enable_unit_files_generic(message
, userdata
, "disable", unit_file_mask
, false, error
);
1725 static int method_preset_unit_files_with_mode(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1727 _cleanup_strv_free_
char **l
= NULL
;
1728 UnitFileChange
*changes
= NULL
;
1729 unsigned n_changes
= 0;
1730 Manager
*m
= userdata
;
1731 UnitFilePresetMode mm
;
1732 UnitFileScope scope
;
1733 int runtime
, force
, r
;
1739 r
= sd_bus_message_read_strv(message
, &l
);
1743 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1748 mm
= UNIT_FILE_PRESET_FULL
;
1750 mm
= unit_file_preset_mode_from_string(mode
);
1755 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1759 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1761 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1763 r
= unit_file_preset(scope
, runtime
, NULL
, l
, mm
, force
, &changes
, &n_changes
);
1767 return reply_unit_file_changes_and_free(m
, message
, r
, changes
, n_changes
);
1770 static int method_disable_unit_files_generic(
1771 sd_bus_message
*message
,
1774 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], UnitFileChange
**changes
, unsigned *n_changes
),
1775 sd_bus_error
*error
) {
1777 _cleanup_strv_free_
char **l
= NULL
;
1778 UnitFileChange
*changes
= NULL
;
1779 unsigned n_changes
= 0;
1780 UnitFileScope scope
;
1786 r
= sd_bus_message_read_strv(message
, &l
);
1790 r
= sd_bus_message_read(message
, "b", &runtime
);
1794 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1796 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1800 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1802 r
= call(scope
, runtime
, NULL
, l
, &changes
, &n_changes
);
1806 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1809 static int method_disable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1810 return method_disable_unit_files_generic(message
, userdata
, "disable", unit_file_disable
, error
);
1813 static int method_unmask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1814 return method_disable_unit_files_generic(message
, userdata
, "enable", unit_file_unmask
, error
);
1817 static int method_set_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1818 UnitFileChange
*changes
= NULL
;
1819 unsigned n_changes
= 0;
1820 Manager
*m
= userdata
;
1821 UnitFileScope scope
;
1828 r
= mac_selinux_access_check(message
, "enable", error
);
1832 r
= sd_bus_message_read(message
, "sb", &name
, &force
);
1836 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1840 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1842 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1844 r
= unit_file_set_default(scope
, NULL
, name
, force
, &changes
, &n_changes
);
1848 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1851 static int method_preset_all_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1852 UnitFileChange
*changes
= NULL
;
1853 unsigned n_changes
= 0;
1854 Manager
*m
= userdata
;
1855 UnitFilePresetMode mm
;
1856 UnitFileScope scope
;
1858 int force
, runtime
, r
;
1863 r
= mac_selinux_access_check(message
, "enable", error
);
1867 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1872 mm
= UNIT_FILE_PRESET_FULL
;
1874 mm
= unit_file_preset_mode_from_string(mode
);
1879 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1883 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1885 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1887 r
= unit_file_preset_all(scope
, runtime
, NULL
, mm
, force
, &changes
, &n_changes
);
1891 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1894 static int method_add_dependency_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1895 _cleanup_strv_free_
char **l
= NULL
;
1896 Manager
*m
= userdata
;
1897 UnitFileChange
*changes
= NULL
;
1898 unsigned n_changes
= 0;
1899 UnitFileScope scope
;
1900 int runtime
, force
, r
;
1908 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1912 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1914 r
= sd_bus_message_read_strv(message
, &l
);
1918 r
= sd_bus_message_read(message
, "ssbb", &target
, &type
, &runtime
, &force
);
1922 dep
= unit_dependency_from_string(type
);
1926 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1928 r
= unit_file_add_dependency(scope
, runtime
, NULL
, l
, target
, dep
, force
, &changes
, &n_changes
);
1932 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1935 const sd_bus_vtable bus_manager_vtable
[] = {
1936 SD_BUS_VTABLE_START(0),
1938 SD_BUS_PROPERTY("Version", "s", property_get_version
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1939 SD_BUS_PROPERTY("Features", "s", property_get_features
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1940 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1941 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1942 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1943 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager
, firmware_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1944 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager
, loader_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1945 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager
, kernel_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1946 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager
, initrd_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1947 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager
, userspace_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1948 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager
, finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1949 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager
, security_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1950 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager
, security_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1951 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager
, generators_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1952 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager
, generators_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1953 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager
, units_load_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1954 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager
, units_load_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1955 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level
, property_set_log_level
, 0, 0),
1956 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target
, property_set_log_target
, 0, 0),
1957 SD_BUS_PROPERTY("NNames", "u", property_get_n_names
, 0, 0),
1958 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1959 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs
, 0, 0),
1960 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_installed_jobs
), 0),
1961 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_failed_jobs
), 0),
1962 SD_BUS_PROPERTY("Progress", "d", property_get_progress
, 0, 0),
1963 SD_BUS_PROPERTY("Environment", "as", NULL
, offsetof(Manager
, environment
), 0),
1964 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool
, offsetof(Manager
, confirm_spawn
), SD_BUS_VTABLE_PROPERTY_CONST
),
1965 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool
, offsetof(Manager
, show_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
1966 SD_BUS_PROPERTY("UnitPath", "as", NULL
, offsetof(Manager
, lookup_paths
.unit_path
), SD_BUS_VTABLE_PROPERTY_CONST
),
1967 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1968 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1969 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec
, property_set_runtime_watchdog
, offsetof(Manager
, runtime_watchdog
), 0),
1970 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec
, bus_property_set_usec
, offsetof(Manager
, shutdown_watchdog
), 0),
1971 SD_BUS_PROPERTY("ControlGroup", "s", NULL
, offsetof(Manager
, cgroup_root
), 0),
1972 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state
, 0, 0),
1973 SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned
, offsetof(Manager
, return_value
), 0),
1974 SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec
, offsetof(Manager
, default_timer_accuracy_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
1975 SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec
, offsetof(Manager
, default_timeout_start_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
1976 SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec
, offsetof(Manager
, default_timeout_stop_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
1977 SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec
, offsetof(Manager
, default_restart_usec
), SD_BUS_VTABLE_PROPERTY_CONST
),
1978 SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec
, offsetof(Manager
, default_start_limit_interval
), SD_BUS_VTABLE_PROPERTY_CONST
),
1979 SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned
, offsetof(Manager
, default_start_limit_burst
), SD_BUS_VTABLE_PROPERTY_CONST
),
1980 SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool
, offsetof(Manager
, default_cpu_accounting
), SD_BUS_VTABLE_PROPERTY_CONST
),
1981 SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool
, offsetof(Manager
, default_blockio_accounting
), SD_BUS_VTABLE_PROPERTY_CONST
),
1982 SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool
, offsetof(Manager
, default_memory_accounting
), SD_BUS_VTABLE_PROPERTY_CONST
),
1983 SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool
, offsetof(Manager
, default_tasks_accounting
), SD_BUS_VTABLE_PROPERTY_CONST
),
1985 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1986 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid
, SD_BUS_VTABLE_UNPRIVILEGED
),
1987 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1988 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1989 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace
, SD_BUS_VTABLE_UNPRIVILEGED
),
1990 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1991 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1992 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1993 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1994 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1995 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1996 SD_BUS_METHOD("KillUnit", "ssi", NULL
, method_kill_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1997 SD_BUS_METHOD("ResetFailedUnit", "s", NULL
, method_reset_failed_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1998 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL
, method_set_unit_properties
, SD_BUS_VTABLE_UNPRIVILEGED
),
1999 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
2000 SD_BUS_METHOD("GetJob", "u", "o", method_get_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
2001 SD_BUS_METHOD("CancelJob", "u", NULL
, method_cancel_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
2002 SD_BUS_METHOD("ClearJobs", NULL
, NULL
, method_clear_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
2003 SD_BUS_METHOD("ResetFailed", NULL
, NULL
, method_reset_failed
, SD_BUS_VTABLE_UNPRIVILEGED
),
2004 SD_BUS_METHOD("ListUnits", NULL
, "a(ssssssouso)", method_list_units
, SD_BUS_VTABLE_UNPRIVILEGED
),
2005 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered
, SD_BUS_VTABLE_UNPRIVILEGED
),
2006 SD_BUS_METHOD("ListJobs", NULL
, "a(usssoo)", method_list_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
2007 SD_BUS_METHOD("Subscribe", NULL
, NULL
, method_subscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
2008 SD_BUS_METHOD("Unsubscribe", NULL
, NULL
, method_unsubscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
2009 SD_BUS_METHOD("Dump", NULL
, "s", method_dump
, SD_BUS_VTABLE_UNPRIVILEGED
),
2010 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
2011 SD_BUS_METHOD("RemoveSnapshot", "s", NULL
, method_remove_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
2012 SD_BUS_METHOD("Reload", NULL
, NULL
, method_reload
, SD_BUS_VTABLE_UNPRIVILEGED
),
2013 SD_BUS_METHOD("Reexecute", NULL
, NULL
, method_reexecute
, SD_BUS_VTABLE_UNPRIVILEGED
),
2014 SD_BUS_METHOD("Exit", NULL
, NULL
, method_exit
, 0),
2015 SD_BUS_METHOD("Reboot", NULL
, NULL
, method_reboot
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
2016 SD_BUS_METHOD("PowerOff", NULL
, NULL
, method_poweroff
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
2017 SD_BUS_METHOD("Halt", NULL
, NULL
, method_halt
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
2018 SD_BUS_METHOD("KExec", NULL
, NULL
, method_kexec
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
2019 SD_BUS_METHOD("SwitchRoot", "ss", NULL
, method_switch_root
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
2020 SD_BUS_METHOD("SetEnvironment", "as", NULL
, method_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
2021 SD_BUS_METHOD("UnsetEnvironment", "as", NULL
, method_unset_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
2022 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL
, method_unset_and_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
2023 SD_BUS_METHOD("ListUnitFiles", NULL
, "a(ss)", method_list_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2024 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state
, SD_BUS_VTABLE_UNPRIVILEGED
),
2025 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2026 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2027 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2028 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2029 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2030 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode
, SD_BUS_VTABLE_UNPRIVILEGED
),
2031 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2032 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2033 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
2034 SD_BUS_METHOD("GetDefaultTarget", NULL
, "s", method_get_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
2035 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2036 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2037 SD_BUS_METHOD("SetExitCode", "y", NULL
, method_set_exit_code
, SD_BUS_VTABLE_UNPRIVILEGED
),
2039 SD_BUS_SIGNAL("UnitNew", "so", 0),
2040 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2041 SD_BUS_SIGNAL("JobNew", "uos", 0),
2042 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2043 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2044 SD_BUS_SIGNAL("UnitFilesChanged", NULL
, 0),
2045 SD_BUS_SIGNAL("Reloading", "b", 0),
2050 static int send_finished(sd_bus
*bus
, void *userdata
) {
2051 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2052 usec_t
*times
= userdata
;
2058 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2062 r
= sd_bus_message_append(message
, "tttttt", times
[0], times
[1], times
[2], times
[3], times
[4], times
[5]);
2066 return sd_bus_send(bus
, message
, NULL
);
2069 void bus_manager_send_finished(
2071 usec_t firmware_usec
,
2075 usec_t userspace_usec
,
2076 usec_t total_usec
) {
2082 r
= bus_foreach_bus(
2095 log_debug_errno(r
, "Failed to send finished signal: %m");
2098 static int send_reloading(sd_bus
*bus
, void *userdata
) {
2099 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2104 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2108 r
= sd_bus_message_append(message
, "b", PTR_TO_INT(userdata
));
2112 return sd_bus_send(bus
, message
, NULL
);
2115 void bus_manager_send_reloading(Manager
*m
, bool active
) {
2120 r
= bus_foreach_bus(m
, NULL
, send_reloading
, INT_TO_PTR(active
));
2122 log_debug_errno(r
, "Failed to send reloading signal: %m");
2125 static int send_changed_signal(sd_bus
*bus
, void *userdata
) {
2128 return sd_bus_emit_properties_changed_strv(bus
,
2129 "/org/freedesktop/systemd1",
2130 "org.freedesktop.systemd1.Manager",
2134 void bus_manager_send_change_signal(Manager
*m
) {
2139 r
= bus_foreach_bus(m
, NULL
, send_changed_signal
, NULL
);
2141 log_debug_errno(r
, "Failed to send manager change signal: %m");