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
) {
84 const char *id
= NULL
;
89 detect_virtualization(&id
);
91 return sd_bus_message_append(reply
, "s", id
);
94 static int property_get_architecture(
97 const char *interface
,
99 sd_bus_message
*reply
,
101 sd_bus_error
*error
) {
106 return sd_bus_message_append(reply
, "s", architecture_to_string(uname_architecture()));
109 static int property_get_tainted(
112 const char *interface
,
113 const char *property
,
114 sd_bus_message
*reply
,
116 sd_bus_error
*error
) {
118 char buf
[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e
= buf
;
119 _cleanup_free_
char *p
= NULL
;
120 Manager
*m
= userdata
;
127 e
= stpcpy(e
, "split-usr:");
129 if (readlink_malloc("/etc/mtab", &p
) < 0)
130 e
= stpcpy(e
, "mtab-not-symlink:");
132 if (access("/proc/cgroups", F_OK
) < 0)
133 e
= stpcpy(e
, "cgroups-missing:");
135 if (clock_is_localtime() > 0)
136 e
= stpcpy(e
, "local-hwclock:");
138 /* remove the last ':' */
142 return sd_bus_message_append(reply
, "s", buf
);
145 static int property_get_log_target(
148 const char *interface
,
149 const char *property
,
150 sd_bus_message
*reply
,
152 sd_bus_error
*error
) {
157 return sd_bus_message_append(reply
, "s", log_target_to_string(log_get_target()));
160 static int property_set_log_target(
163 const char *interface
,
164 const char *property
,
165 sd_bus_message
*value
,
167 sd_bus_error
*error
) {
175 r
= sd_bus_message_read(value
, "s", &t
);
179 return log_set_target_from_string(t
);
182 static int property_get_log_level(
185 const char *interface
,
186 const char *property
,
187 sd_bus_message
*reply
,
189 sd_bus_error
*error
) {
191 _cleanup_free_
char *t
= NULL
;
197 r
= log_level_to_string_alloc(log_get_max_level(), &t
);
201 return sd_bus_message_append(reply
, "s", t
);
204 static int property_set_log_level(
207 const char *interface
,
208 const char *property
,
209 sd_bus_message
*value
,
211 sd_bus_error
*error
) {
219 r
= sd_bus_message_read(value
, "s", &t
);
223 return log_set_max_level_from_string(t
);
226 static int property_get_n_names(
229 const char *interface
,
230 const char *property
,
231 sd_bus_message
*reply
,
233 sd_bus_error
*error
) {
235 Manager
*m
= userdata
;
241 return sd_bus_message_append(reply
, "u", (uint32_t) hashmap_size(m
->units
));
244 static int property_get_n_failed_units(
247 const char *interface
,
248 const char *property
,
249 sd_bus_message
*reply
,
251 sd_bus_error
*error
) {
253 Manager
*m
= userdata
;
259 return sd_bus_message_append(reply
, "u", (uint32_t) set_size(m
->failed_units
));
262 static int property_get_n_jobs(
265 const char *interface
,
266 const char *property
,
267 sd_bus_message
*reply
,
269 sd_bus_error
*error
) {
271 Manager
*m
= userdata
;
277 return sd_bus_message_append(reply
, "u", (uint32_t) hashmap_size(m
->jobs
));
280 static int property_get_progress(
283 const char *interface
,
284 const char *property
,
285 sd_bus_message
*reply
,
287 sd_bus_error
*error
) {
289 Manager
*m
= userdata
;
296 if (dual_timestamp_is_set(&m
->finish_timestamp
))
299 d
= 1.0 - ((double) hashmap_size(m
->jobs
) / (double) m
->n_installed_jobs
);
301 return sd_bus_message_append(reply
, "d", d
);
304 static int property_get_system_state(
307 const char *interface
,
308 const char *property
,
309 sd_bus_message
*reply
,
311 sd_bus_error
*error
) {
313 Manager
*m
= userdata
;
319 return sd_bus_message_append(reply
, "s", manager_state_to_string(manager_state(m
)));
322 static int property_set_runtime_watchdog(
325 const char *interface
,
326 const char *property
,
327 sd_bus_message
*value
,
329 sd_bus_error
*error
) {
331 usec_t
*t
= userdata
;
337 assert_cc(sizeof(usec_t
) == sizeof(uint64_t));
339 r
= sd_bus_message_read(value
, "t", t
);
343 return watchdog_set_timeout(t
);
346 static int method_get_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
347 _cleanup_free_
char *path
= NULL
;
348 Manager
*m
= userdata
;
356 /* Anyone can call this method */
358 r
= sd_bus_message_read(message
, "s", &name
);
363 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
366 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
370 r
= sd_bus_creds_get_pid(creds
, &pid
);
374 u
= manager_get_unit_by_pid(m
, pid
);
376 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Client not member of any unit.");
378 u
= manager_get_unit(m
, name
);
380 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s not loaded.", name
);
383 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
387 path
= unit_dbus_path(u
);
391 return sd_bus_reply_method_return(message
, "o", path
);
394 static int method_get_unit_by_pid(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
395 _cleanup_free_
char *path
= NULL
;
396 Manager
*m
= userdata
;
404 assert_cc(sizeof(pid_t
) == sizeof(uint32_t));
406 /* Anyone can call this method */
408 r
= sd_bus_message_read(message
, "u", &pid
);
412 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid PID " PID_FMT
, pid
);
415 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
417 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
421 r
= sd_bus_creds_get_pid(creds
, &pid
);
426 u
= manager_get_unit_by_pid(m
, pid
);
428 return sd_bus_error_setf(error
, BUS_ERROR_NO_UNIT_FOR_PID
, "PID "PID_FMT
" does not belong to any loaded unit.", pid
);
430 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
434 path
= unit_dbus_path(u
);
438 return sd_bus_reply_method_return(message
, "o", path
);
441 static int method_load_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
442 _cleanup_free_
char *path
= NULL
;
443 Manager
*m
= userdata
;
451 /* Anyone can call this method */
453 r
= sd_bus_message_read(message
, "s", &name
);
458 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
461 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
465 r
= sd_bus_creds_get_pid(creds
, &pid
);
469 u
= manager_get_unit_by_pid(m
, pid
);
471 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Client not member of any unit.");
473 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
478 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
482 path
= unit_dbus_path(u
);
486 return sd_bus_reply_method_return(message
, "o", path
);
489 static int method_start_unit_generic(sd_bus_message
*message
, Manager
*m
, JobType job_type
, bool reload_if_possible
, sd_bus_error
*error
) {
497 r
= sd_bus_message_read(message
, "s", &name
);
501 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
505 return bus_unit_method_start_generic(message
, u
, job_type
, reload_if_possible
, error
);
508 static int method_start_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
509 return method_start_unit_generic(message
, userdata
, JOB_START
, false, error
);
512 static int method_stop_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
513 return method_start_unit_generic(message
, userdata
, JOB_STOP
, false, error
);
516 static int method_reload_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
517 return method_start_unit_generic(message
, userdata
, JOB_RELOAD
, false, error
);
520 static int method_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
521 return method_start_unit_generic(message
, userdata
, JOB_RESTART
, false, error
);
524 static int method_try_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
525 return method_start_unit_generic(message
, userdata
, JOB_TRY_RESTART
, false, error
);
528 static int method_reload_or_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
529 return method_start_unit_generic(message
, userdata
, JOB_RESTART
, true, error
);
532 static int method_reload_or_try_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
533 return method_start_unit_generic(message
, userdata
, JOB_TRY_RESTART
, true, error
);
536 static int method_start_unit_replace(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
537 Manager
*m
= userdata
;
538 const char *old_name
;
545 r
= sd_bus_message_read(message
, "s", &old_name
);
549 u
= manager_get_unit(m
, old_name
);
550 if (!u
|| !u
->job
|| u
->job
->type
!= JOB_START
)
551 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "No job queued for unit %s", old_name
);
553 return method_start_unit_generic(message
, m
, JOB_START
, false, error
);
556 static int method_kill_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
557 Manager
*m
= userdata
;
565 r
= sd_bus_message_read(message
, "s", &name
);
569 u
= manager_get_unit(m
, name
);
571 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
573 return bus_unit_method_kill(message
, u
, error
);
576 static int method_reset_failed_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
577 Manager
*m
= userdata
;
585 r
= sd_bus_message_read(message
, "s", &name
);
589 u
= manager_get_unit(m
, name
);
591 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
593 return bus_unit_method_reset_failed(message
, u
, error
);
596 static int method_set_unit_properties(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
597 Manager
*m
= userdata
;
605 r
= sd_bus_message_read(message
, "s", &name
);
609 u
= manager_get_unit(m
, name
);
611 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
613 return bus_unit_method_set_properties(message
, u
, error
);
616 static int transient_unit_from_message(
618 sd_bus_message
*message
,
621 sd_bus_error
*error
) {
630 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
634 if (u
->load_state
!= UNIT_NOT_FOUND
||
635 set_size(u
->dependencies
[UNIT_REFERENCED_BY
]) > 0)
636 return sd_bus_error_setf(error
, BUS_ERROR_UNIT_EXISTS
, "Unit %s already exists.", name
);
638 /* OK, the unit failed to load and is unreferenced, now let's
639 * fill in the transient data instead */
640 r
= unit_make_transient(u
);
644 /* Set our properties */
645 r
= bus_unit_set_properties(u
, message
, UNIT_RUNTIME
, false, error
);
654 static int transient_aux_units_from_message(
656 sd_bus_message
*message
,
657 sd_bus_error
*error
) {
666 r
= sd_bus_message_enter_container(message
, 'a', "(sa(sv))");
670 while ((r
= sd_bus_message_enter_container(message
, 'r', "sa(sv)")) > 0) {
671 r
= sd_bus_message_read(message
, "s", &name
);
675 r
= transient_unit_from_message(m
, message
, name
, &u
, error
);
676 if (r
< 0 && r
!= -EEXIST
)
685 r
= sd_bus_message_exit_container(message
);
692 r
= sd_bus_message_exit_container(message
);
699 static int method_start_transient_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
700 const char *name
, *smode
;
701 Manager
*m
= userdata
;
710 r
= mac_selinux_access_check(message
, "start", error
);
714 r
= sd_bus_message_read(message
, "ss", &name
, &smode
);
718 t
= unit_name_to_type(name
);
720 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid unit type.");
722 if (!unit_vtable
[t
]->can_transient
)
723 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unit type %s does not support transient units.", unit_type_to_string(t
));
725 mode
= job_mode_from_string(smode
);
727 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Job mode %s is invalid.", smode
);
729 r
= bus_verify_manage_units_async(m
, message
, error
);
733 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
735 r
= transient_unit_from_message(m
, message
, name
, &u
, error
);
739 r
= transient_aux_units_from_message(m
, message
, error
);
743 /* And load this stub fully */
748 manager_dispatch_load_queue(m
);
750 /* Finally, start it */
751 return bus_unit_queue_job(message
, u
, JOB_START
, mode
, false, error
);
754 static int method_get_job(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
755 _cleanup_free_
char *path
= NULL
;
756 Manager
*m
= userdata
;
764 /* Anyone can call this method */
766 r
= sd_bus_message_read(message
, "u", &id
);
770 j
= manager_get_job(m
, id
);
772 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "Job %u does not exist.", (unsigned) id
);
774 r
= mac_selinux_unit_access_check(j
->unit
, message
, "status", error
);
778 path
= job_dbus_path(j
);
782 return sd_bus_reply_method_return(message
, "o", path
);
785 static int method_cancel_job(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
786 Manager
*m
= userdata
;
794 r
= sd_bus_message_read(message
, "u", &id
);
798 j
= manager_get_job(m
, id
);
800 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "Job %u does not exist.", (unsigned) id
);
802 return bus_job_method_cancel(message
, j
, error
);
805 static int method_clear_jobs(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
806 Manager
*m
= userdata
;
812 r
= mac_selinux_access_check(message
, "reload", error
);
816 r
= bus_verify_manage_units_async(m
, message
, error
);
820 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
822 manager_clear_jobs(m
);
824 return sd_bus_reply_method_return(message
, NULL
);
827 static int method_reset_failed(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
828 Manager
*m
= userdata
;
834 r
= mac_selinux_access_check(message
, "reload", error
);
838 r
= bus_verify_manage_units_async(m
, message
, error
);
842 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
844 manager_reset_failed(m
);
846 return sd_bus_reply_method_return(message
, NULL
);
849 static int list_units_filtered(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
, char **states
) {
850 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
851 Manager
*m
= userdata
;
860 /* Anyone can call this method */
862 r
= mac_selinux_access_check(message
, "status", error
);
866 r
= sd_bus_message_new_method_return(message
, &reply
);
870 r
= sd_bus_message_open_container(reply
, 'a', "(ssssssouso)");
874 HASHMAP_FOREACH_KEY(u
, k
, m
->units
, i
) {
875 _cleanup_free_
char *unit_path
= NULL
, *job_path
= NULL
;
881 following
= unit_following(u
);
883 if (!strv_isempty(states
) &&
884 !strv_contains(states
, unit_load_state_to_string(u
->load_state
)) &&
885 !strv_contains(states
, unit_active_state_to_string(unit_active_state(u
))) &&
886 !strv_contains(states
, unit_sub_state_to_string(u
)))
889 unit_path
= unit_dbus_path(u
);
894 job_path
= job_dbus_path(u
->job
);
899 r
= sd_bus_message_append(
900 reply
, "(ssssssouso)",
903 unit_load_state_to_string(u
->load_state
),
904 unit_active_state_to_string(unit_active_state(u
)),
905 unit_sub_state_to_string(u
),
906 following
? following
->id
: "",
908 u
->job
? u
->job
->id
: 0,
909 u
->job
? job_type_to_string(u
->job
->type
) : "",
910 job_path
? job_path
: "/");
915 r
= sd_bus_message_close_container(reply
);
919 return sd_bus_send(NULL
, reply
, NULL
);
922 static int method_list_units(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
923 return list_units_filtered(message
, userdata
, error
, NULL
);
926 static int method_list_units_filtered(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
927 _cleanup_strv_free_
char **states
= NULL
;
930 r
= sd_bus_message_read_strv(message
, &states
);
934 return list_units_filtered(message
, userdata
, error
, states
);
937 static int method_list_jobs(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
938 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
939 Manager
*m
= userdata
;
947 /* Anyone can call this method */
949 r
= mac_selinux_access_check(message
, "status", error
);
953 r
= sd_bus_message_new_method_return(message
, &reply
);
957 r
= sd_bus_message_open_container(reply
, 'a', "(usssoo)");
961 HASHMAP_FOREACH(j
, m
->jobs
, i
) {
962 _cleanup_free_
char *unit_path
= NULL
, *job_path
= NULL
;
964 job_path
= job_dbus_path(j
);
968 unit_path
= unit_dbus_path(j
->unit
);
972 r
= sd_bus_message_append(
976 job_type_to_string(j
->type
),
977 job_state_to_string(j
->state
),
984 r
= sd_bus_message_close_container(reply
);
988 return sd_bus_send(NULL
, reply
, NULL
);
991 static int method_subscribe(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
992 Manager
*m
= userdata
;
998 /* Anyone can call this method */
1000 r
= mac_selinux_access_check(message
, "status", error
);
1004 if (sd_bus_message_get_bus(message
) == m
->api_bus
) {
1006 /* Note that direct bus connection subscribe by
1007 * default, we only track peers on the API bus here */
1009 if (!m
->subscribed
) {
1010 r
= sd_bus_track_new(sd_bus_message_get_bus(message
), &m
->subscribed
, NULL
, NULL
);
1015 r
= sd_bus_track_add_sender(m
->subscribed
, message
);
1019 return sd_bus_error_setf(error
, BUS_ERROR_ALREADY_SUBSCRIBED
, "Client is already subscribed.");
1022 return sd_bus_reply_method_return(message
, NULL
);
1025 static int method_unsubscribe(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1026 Manager
*m
= userdata
;
1032 /* Anyone can call this method */
1034 r
= mac_selinux_access_check(message
, "status", error
);
1038 if (sd_bus_message_get_bus(message
) == m
->api_bus
) {
1039 r
= sd_bus_track_remove_sender(m
->subscribed
, message
);
1043 return sd_bus_error_setf(error
, BUS_ERROR_NOT_SUBSCRIBED
, "Client is not subscribed.");
1046 return sd_bus_reply_method_return(message
, NULL
);
1049 static int method_dump(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1050 _cleanup_free_
char *dump
= NULL
;
1051 _cleanup_fclose_
FILE *f
= NULL
;
1052 Manager
*m
= userdata
;
1059 /* Anyone can call this method */
1061 r
= mac_selinux_access_check(message
, "status", error
);
1065 f
= open_memstream(&dump
, &size
);
1069 manager_dump_units(m
, f
, NULL
);
1070 manager_dump_jobs(m
, f
, NULL
);
1077 return sd_bus_reply_method_return(message
, "s", dump
);
1080 static int method_create_snapshot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1081 _cleanup_free_
char *path
= NULL
;
1082 Manager
*m
= userdata
;
1091 r
= mac_selinux_access_check(message
, "start", error
);
1095 r
= sd_bus_message_read(message
, "sb", &name
, &cleanup
);
1102 r
= bus_verify_manage_units_async(m
, message
, error
);
1106 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1108 r
= snapshot_create(m
, name
, cleanup
, error
, &s
);
1112 path
= unit_dbus_path(UNIT(s
));
1116 return sd_bus_reply_method_return(message
, "o", path
);
1119 static int method_remove_snapshot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1120 Manager
*m
= userdata
;
1128 r
= sd_bus_message_read(message
, "s", &name
);
1132 u
= manager_get_unit(m
, name
);
1134 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s does not exist.", name
);
1136 if (u
->type
!= UNIT_SNAPSHOT
)
1137 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not a snapshot", name
);
1139 return bus_snapshot_method_remove(message
, u
, error
);
1142 static int method_reload(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1143 Manager
*m
= userdata
;
1149 r
= mac_selinux_access_check(message
, "reload", error
);
1153 r
= bus_verify_reload_daemon_async(m
, message
, error
);
1157 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1159 /* Instead of sending the reply back right away, we just
1160 * remember that we need to and then send it after the reload
1161 * is finished. That way the caller knows when the reload
1164 assert(!m
->queued_message
);
1165 r
= sd_bus_message_new_method_return(message
, &m
->queued_message
);
1169 m
->exit_code
= MANAGER_RELOAD
;
1174 static int method_reexecute(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1175 Manager
*m
= userdata
;
1181 r
= mac_selinux_access_check(message
, "reload", error
);
1185 r
= bus_verify_reload_daemon_async(m
, message
, error
);
1189 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1191 /* We don't send a reply back here, the client should
1192 * just wait for us disconnecting. */
1194 m
->exit_code
= MANAGER_REEXECUTE
;
1198 static int method_exit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1199 Manager
*m
= userdata
;
1205 r
= mac_selinux_access_check(message
, "halt", error
);
1209 if (m
->running_as
== MANAGER_SYSTEM
)
1210 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Exit is only supported for user service managers.");
1212 m
->exit_code
= MANAGER_EXIT
;
1214 return sd_bus_reply_method_return(message
, NULL
);
1217 static int method_reboot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1218 Manager
*m
= userdata
;
1224 r
= mac_selinux_access_check(message
, "reboot", error
);
1228 if (m
->running_as
!= MANAGER_SYSTEM
)
1229 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Reboot is only supported for system managers.");
1231 m
->exit_code
= MANAGER_REBOOT
;
1233 return sd_bus_reply_method_return(message
, NULL
);
1236 static int method_poweroff(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1237 Manager
*m
= userdata
;
1243 r
= mac_selinux_access_check(message
, "halt", error
);
1247 if (m
->running_as
!= MANAGER_SYSTEM
)
1248 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Powering off is only supported for system managers.");
1250 m
->exit_code
= MANAGER_POWEROFF
;
1252 return sd_bus_reply_method_return(message
, NULL
);
1255 static int method_halt(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1256 Manager
*m
= userdata
;
1262 r
= mac_selinux_access_check(message
, "halt", error
);
1266 if (m
->running_as
!= MANAGER_SYSTEM
)
1267 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Halt is only supported for system managers.");
1269 m
->exit_code
= MANAGER_HALT
;
1271 return sd_bus_reply_method_return(message
, NULL
);
1274 static int method_kexec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1275 Manager
*m
= userdata
;
1281 r
= mac_selinux_access_check(message
, "reboot", error
);
1285 if (m
->running_as
!= MANAGER_SYSTEM
)
1286 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "KExec is only supported for system managers.");
1288 m
->exit_code
= MANAGER_KEXEC
;
1290 return sd_bus_reply_method_return(message
, NULL
);
1293 static int method_switch_root(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1294 char *ri
= NULL
, *rt
= NULL
;
1295 const char *root
, *init
;
1296 Manager
*m
= userdata
;
1302 r
= mac_selinux_access_check(message
, "reboot", error
);
1306 if (m
->running_as
!= MANAGER_SYSTEM
)
1307 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Root switching is only supported by system manager.");
1309 r
= sd_bus_message_read(message
, "ss", &root
, &init
);
1313 if (path_equal(root
, "/") || !path_is_absolute(root
))
1314 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid switch root path %s", root
);
1317 if (isempty(init
)) {
1318 if (!path_is_os_tree(root
))
1319 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
);
1321 _cleanup_free_
char *p
= NULL
;
1323 if (!path_is_absolute(init
))
1324 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid init path %s", init
);
1326 p
= strappend(root
, init
);
1330 if (access(p
, X_OK
) < 0)
1331 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified init binary %s does not exist.", p
);
1338 if (!isempty(init
)) {
1346 free(m
->switch_root
);
1347 m
->switch_root
= rt
;
1349 free(m
->switch_root_init
);
1350 m
->switch_root_init
= ri
;
1352 m
->exit_code
= MANAGER_SWITCH_ROOT
;
1354 return sd_bus_reply_method_return(message
, NULL
);
1357 static int method_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1358 _cleanup_strv_free_
char **plus
= NULL
;
1359 Manager
*m
= userdata
;
1365 r
= mac_selinux_access_check(message
, "reload", error
);
1369 r
= sd_bus_message_read_strv(message
, &plus
);
1372 if (!strv_env_is_valid(plus
))
1373 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1375 r
= bus_verify_set_environment_async(m
, message
, error
);
1379 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1381 r
= manager_environment_add(m
, NULL
, plus
);
1385 return sd_bus_reply_method_return(message
, NULL
);
1388 static int method_unset_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1389 _cleanup_strv_free_
char **minus
= NULL
;
1390 Manager
*m
= userdata
;
1396 r
= mac_selinux_access_check(message
, "reload", error
);
1400 r
= sd_bus_message_read_strv(message
, &minus
);
1404 if (!strv_env_name_or_assignment_is_valid(minus
))
1405 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1407 r
= bus_verify_set_environment_async(m
, message
, error
);
1411 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1413 r
= manager_environment_add(m
, minus
, NULL
);
1417 return sd_bus_reply_method_return(message
, NULL
);
1420 static int method_unset_and_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1421 _cleanup_strv_free_
char **minus
= NULL
, **plus
= NULL
;
1422 Manager
*m
= userdata
;
1428 r
= mac_selinux_access_check(message
, "reload", error
);
1432 r
= sd_bus_message_read_strv(message
, &minus
);
1436 r
= sd_bus_message_read_strv(message
, &plus
);
1440 if (!strv_env_name_or_assignment_is_valid(minus
))
1441 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1442 if (!strv_env_is_valid(plus
))
1443 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1445 r
= bus_verify_set_environment_async(m
, message
, error
);
1449 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1451 r
= manager_environment_add(m
, minus
, plus
);
1455 return sd_bus_reply_method_return(message
, NULL
);
1458 static int method_list_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1459 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1460 Manager
*m
= userdata
;
1469 /* Anyone can call this method */
1471 r
= mac_selinux_access_check(message
, "status", error
);
1475 r
= sd_bus_message_new_method_return(message
, &reply
);
1479 h
= hashmap_new(&string_hash_ops
);
1483 r
= unit_file_get_list(m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
, NULL
, h
);
1487 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
1491 HASHMAP_FOREACH(item
, h
, i
) {
1493 r
= sd_bus_message_append(reply
, "(ss)", item
->path
, unit_file_state_to_string(item
->state
));
1498 unit_file_list_free(h
);
1500 r
= sd_bus_message_close_container(reply
);
1504 return sd_bus_send(NULL
, reply
, NULL
);
1507 unit_file_list_free(h
);
1511 static int method_get_unit_file_state(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1512 Manager
*m
= userdata
;
1514 UnitFileState state
;
1515 UnitFileScope scope
;
1521 /* Anyone can call this method */
1523 r
= mac_selinux_access_check(message
, "status", error
);
1527 r
= sd_bus_message_read(message
, "s", &name
);
1531 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1533 state
= unit_file_get_state(scope
, NULL
, name
);
1537 return sd_bus_reply_method_return(message
, "s", unit_file_state_to_string(state
));
1540 static int method_get_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1541 _cleanup_free_
char *default_target
= NULL
;
1542 Manager
*m
= userdata
;
1543 UnitFileScope scope
;
1549 /* Anyone can call this method */
1551 r
= mac_selinux_access_check(message
, "status", error
);
1555 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1557 r
= unit_file_get_default(scope
, NULL
, &default_target
);
1561 return sd_bus_reply_method_return(message
, "s", default_target
);
1564 static int send_unit_files_changed(sd_bus
*bus
, void *userdata
) {
1565 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
1570 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1574 return sd_bus_send(bus
, message
, NULL
);
1577 static int reply_unit_file_changes_and_free(
1579 sd_bus_message
*message
,
1580 int carries_install_info
,
1581 UnitFileChange
*changes
,
1582 unsigned n_changes
) {
1584 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1588 if (n_changes
> 0) {
1589 r
= bus_foreach_bus(m
, NULL
, send_unit_files_changed
, NULL
);
1591 log_debug_errno(r
, "Failed to send UnitFilesChanged signal: %m");
1594 r
= sd_bus_message_new_method_return(message
, &reply
);
1598 if (carries_install_info
>= 0) {
1599 r
= sd_bus_message_append(reply
, "b", carries_install_info
);
1604 r
= sd_bus_message_open_container(reply
, 'a', "(sss)");
1608 for (i
= 0; i
< n_changes
; i
++) {
1609 r
= sd_bus_message_append(
1611 unit_file_change_type_to_string(changes
[i
].type
),
1618 r
= sd_bus_message_close_container(reply
);
1622 return sd_bus_send(NULL
, reply
, NULL
);
1625 unit_file_changes_free(changes
, n_changes
);
1629 static int method_enable_unit_files_generic(
1630 sd_bus_message
*message
,
1633 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], bool force
, UnitFileChange
**changes
, unsigned *n_changes
),
1634 bool carries_install_info
,
1635 sd_bus_error
*error
) {
1637 _cleanup_strv_free_
char **l
= NULL
;
1638 UnitFileChange
*changes
= NULL
;
1639 unsigned n_changes
= 0;
1640 UnitFileScope scope
;
1641 int runtime
, force
, r
;
1646 r
= sd_bus_message_read_strv(message
, &l
);
1650 r
= sd_bus_message_read(message
, "bb", &runtime
, &force
);
1654 r
= mac_selinux_unit_access_check_strv(l
, message
, m
, verb
, error
);
1658 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1662 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1664 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1666 r
= call(scope
, runtime
, NULL
, l
, force
, &changes
, &n_changes
);
1670 return reply_unit_file_changes_and_free(m
, message
, carries_install_info
? r
: -1, changes
, n_changes
);
1673 static int method_enable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1674 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_enable
, true, error
);
1677 static int method_reenable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1678 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_reenable
, true, error
);
1681 static int method_link_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1682 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_link
, false, error
);
1685 static int unit_file_preset_without_mode(UnitFileScope scope
, bool runtime
, const char *root_dir
, char **files
, bool force
, UnitFileChange
**changes
, unsigned *n_changes
) {
1686 return unit_file_preset(scope
, runtime
, root_dir
, files
, UNIT_FILE_PRESET_FULL
, force
, changes
, n_changes
);
1689 static int method_preset_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1690 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_preset_without_mode
, true, error
);
1693 static int method_mask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1694 return method_enable_unit_files_generic(message
, userdata
, "disable", unit_file_mask
, false, error
);
1697 static int method_preset_unit_files_with_mode(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1699 _cleanup_strv_free_
char **l
= NULL
;
1700 UnitFileChange
*changes
= NULL
;
1701 unsigned n_changes
= 0;
1702 Manager
*m
= userdata
;
1703 UnitFilePresetMode mm
;
1704 UnitFileScope scope
;
1705 int runtime
, force
, r
;
1711 r
= sd_bus_message_read_strv(message
, &l
);
1715 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1720 mm
= UNIT_FILE_PRESET_FULL
;
1722 mm
= unit_file_preset_mode_from_string(mode
);
1727 r
= mac_selinux_unit_access_check_strv(l
, message
, m
, "enable", error
);
1731 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1735 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1737 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1739 r
= unit_file_preset(scope
, runtime
, NULL
, l
, mm
, force
, &changes
, &n_changes
);
1743 return reply_unit_file_changes_and_free(m
, message
, r
, changes
, n_changes
);
1746 static int method_disable_unit_files_generic(
1747 sd_bus_message
*message
,
1750 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], UnitFileChange
**changes
, unsigned *n_changes
),
1751 sd_bus_error
*error
) {
1753 _cleanup_strv_free_
char **l
= NULL
;
1754 UnitFileChange
*changes
= NULL
;
1755 unsigned n_changes
= 0;
1756 UnitFileScope scope
;
1762 r
= sd_bus_message_read_strv(message
, &l
);
1766 r
= sd_bus_message_read(message
, "b", &runtime
);
1770 r
= mac_selinux_unit_access_check_strv(l
, message
, m
, verb
, error
);
1774 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1776 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1780 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1782 r
= call(scope
, runtime
, NULL
, l
, &changes
, &n_changes
);
1786 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1789 static int method_disable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1790 return method_disable_unit_files_generic(message
, userdata
, "disable", unit_file_disable
, error
);
1793 static int method_unmask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1794 return method_disable_unit_files_generic(message
, userdata
, "enable", unit_file_unmask
, error
);
1797 static int method_set_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1798 UnitFileChange
*changes
= NULL
;
1799 unsigned n_changes
= 0;
1800 Manager
*m
= userdata
;
1801 UnitFileScope scope
;
1808 r
= mac_selinux_access_check(message
, "enable", error
);
1812 r
= sd_bus_message_read(message
, "sb", &name
, &force
);
1816 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1820 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1822 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1824 r
= unit_file_set_default(scope
, NULL
, name
, force
, &changes
, &n_changes
);
1828 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1831 static int method_preset_all_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1832 UnitFileChange
*changes
= NULL
;
1833 unsigned n_changes
= 0;
1834 Manager
*m
= userdata
;
1835 UnitFilePresetMode mm
;
1836 UnitFileScope scope
;
1838 int force
, runtime
, r
;
1843 r
= mac_selinux_access_check(message
, "enable", error
);
1847 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1852 mm
= UNIT_FILE_PRESET_FULL
;
1854 mm
= unit_file_preset_mode_from_string(mode
);
1859 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1863 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1865 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1867 r
= unit_file_preset_all(scope
, runtime
, NULL
, mm
, force
, &changes
, &n_changes
);
1871 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1874 static int method_add_dependency_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1875 _cleanup_strv_free_
char **l
= NULL
;
1876 Manager
*m
= userdata
;
1877 UnitFileChange
*changes
= NULL
;
1878 unsigned n_changes
= 0;
1879 UnitFileScope scope
;
1880 int runtime
, force
, r
;
1888 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1892 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1894 r
= sd_bus_message_read_strv(message
, &l
);
1898 r
= sd_bus_message_read(message
, "ssbb", &target
, &type
, &runtime
, &force
);
1902 dep
= unit_dependency_from_string(type
);
1906 r
= mac_selinux_unit_access_check_strv(l
, message
, m
, "enable", error
);
1910 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1912 r
= unit_file_add_dependency(scope
, runtime
, NULL
, l
, target
, dep
, force
, &changes
, &n_changes
);
1916 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1919 const sd_bus_vtable bus_manager_vtable
[] = {
1920 SD_BUS_VTABLE_START(0),
1922 SD_BUS_PROPERTY("Version", "s", property_get_version
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1923 SD_BUS_PROPERTY("Features", "s", property_get_features
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1924 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1925 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1926 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1927 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager
, firmware_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1928 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager
, loader_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1929 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager
, kernel_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1930 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager
, initrd_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1931 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager
, userspace_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1932 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager
, finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1933 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager
, security_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1934 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager
, security_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1935 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager
, generators_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1936 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager
, generators_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1937 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager
, units_load_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1938 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager
, units_load_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1939 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level
, property_set_log_level
, 0, 0),
1940 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target
, property_set_log_target
, 0, 0),
1941 SD_BUS_PROPERTY("NNames", "u", property_get_n_names
, 0, 0),
1942 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1943 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs
, 0, 0),
1944 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_installed_jobs
), 0),
1945 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_failed_jobs
), 0),
1946 SD_BUS_PROPERTY("Progress", "d", property_get_progress
, 0, 0),
1947 SD_BUS_PROPERTY("Environment", "as", NULL
, offsetof(Manager
, environment
), 0),
1948 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool
, offsetof(Manager
, confirm_spawn
), SD_BUS_VTABLE_PROPERTY_CONST
),
1949 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool
, offsetof(Manager
, show_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
1950 SD_BUS_PROPERTY("UnitPath", "as", NULL
, offsetof(Manager
, lookup_paths
.unit_path
), SD_BUS_VTABLE_PROPERTY_CONST
),
1951 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1952 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1953 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec
, property_set_runtime_watchdog
, offsetof(Manager
, runtime_watchdog
), 0),
1954 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec
, bus_property_set_usec
, offsetof(Manager
, shutdown_watchdog
), 0),
1955 SD_BUS_PROPERTY("ControlGroup", "s", NULL
, offsetof(Manager
, cgroup_root
), 0),
1956 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state
, 0, 0),
1958 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1959 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid
, SD_BUS_VTABLE_UNPRIVILEGED
),
1960 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1961 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1962 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace
, SD_BUS_VTABLE_UNPRIVILEGED
),
1963 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1964 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1965 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1966 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1967 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1968 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1969 SD_BUS_METHOD("KillUnit", "ssi", NULL
, method_kill_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1970 SD_BUS_METHOD("ResetFailedUnit", "s", NULL
, method_reset_failed_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1971 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL
, method_set_unit_properties
, SD_BUS_VTABLE_UNPRIVILEGED
),
1972 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1973 SD_BUS_METHOD("GetJob", "u", "o", method_get_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
1974 SD_BUS_METHOD("CancelJob", "u", NULL
, method_cancel_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
1975 SD_BUS_METHOD("ClearJobs", NULL
, NULL
, method_clear_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
1976 SD_BUS_METHOD("ResetFailed", NULL
, NULL
, method_reset_failed
, SD_BUS_VTABLE_UNPRIVILEGED
),
1977 SD_BUS_METHOD("ListUnits", NULL
, "a(ssssssouso)", method_list_units
, SD_BUS_VTABLE_UNPRIVILEGED
),
1978 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered
, SD_BUS_VTABLE_UNPRIVILEGED
),
1979 SD_BUS_METHOD("ListJobs", NULL
, "a(usssoo)", method_list_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
1980 SD_BUS_METHOD("Subscribe", NULL
, NULL
, method_subscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
1981 SD_BUS_METHOD("Unsubscribe", NULL
, NULL
, method_unsubscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
1982 SD_BUS_METHOD("Dump", NULL
, "s", method_dump
, SD_BUS_VTABLE_UNPRIVILEGED
),
1983 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
1984 SD_BUS_METHOD("RemoveSnapshot", "s", NULL
, method_remove_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
1985 SD_BUS_METHOD("Reload", NULL
, NULL
, method_reload
, SD_BUS_VTABLE_UNPRIVILEGED
),
1986 SD_BUS_METHOD("Reexecute", NULL
, NULL
, method_reexecute
, SD_BUS_VTABLE_UNPRIVILEGED
),
1987 SD_BUS_METHOD("Exit", NULL
, NULL
, method_exit
, 0),
1988 SD_BUS_METHOD("Reboot", NULL
, NULL
, method_reboot
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1989 SD_BUS_METHOD("PowerOff", NULL
, NULL
, method_poweroff
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1990 SD_BUS_METHOD("Halt", NULL
, NULL
, method_halt
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1991 SD_BUS_METHOD("KExec", NULL
, NULL
, method_kexec
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1992 SD_BUS_METHOD("SwitchRoot", "ss", NULL
, method_switch_root
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1993 SD_BUS_METHOD("SetEnvironment", "as", NULL
, method_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1994 SD_BUS_METHOD("UnsetEnvironment", "as", NULL
, method_unset_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1995 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL
, method_unset_and_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1996 SD_BUS_METHOD("ListUnitFiles", NULL
, "a(ss)", method_list_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1997 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state
, SD_BUS_VTABLE_UNPRIVILEGED
),
1998 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1999 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2000 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2001 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2002 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2003 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode
, SD_BUS_VTABLE_UNPRIVILEGED
),
2004 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2005 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2006 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
2007 SD_BUS_METHOD("GetDefaultTarget", NULL
, "s", method_get_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
2008 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2009 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2011 SD_BUS_SIGNAL("UnitNew", "so", 0),
2012 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2013 SD_BUS_SIGNAL("JobNew", "uos", 0),
2014 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2015 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2016 SD_BUS_SIGNAL("UnitFilesChanged", NULL
, 0),
2017 SD_BUS_SIGNAL("Reloading", "b", 0),
2022 static int send_finished(sd_bus
*bus
, void *userdata
) {
2023 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2024 usec_t
*times
= userdata
;
2030 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2034 r
= sd_bus_message_append(message
, "tttttt", times
[0], times
[1], times
[2], times
[3], times
[4], times
[5]);
2038 return sd_bus_send(bus
, message
, NULL
);
2041 void bus_manager_send_finished(
2043 usec_t firmware_usec
,
2047 usec_t userspace_usec
,
2048 usec_t total_usec
) {
2054 r
= bus_foreach_bus(
2067 log_debug_errno(r
, "Failed to send finished signal: %m");
2070 static int send_reloading(sd_bus
*bus
, void *userdata
) {
2071 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2076 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2080 r
= sd_bus_message_append(message
, "b", PTR_TO_INT(userdata
));
2084 return sd_bus_send(bus
, message
, NULL
);
2087 void bus_manager_send_reloading(Manager
*m
, bool active
) {
2092 r
= bus_foreach_bus(m
, NULL
, send_reloading
, INT_TO_PTR(active
));
2094 log_debug_errno(r
, "Failed to send reloading signal: %m");
2097 static int send_changed_signal(sd_bus
*bus
, void *userdata
) {
2100 return sd_bus_emit_properties_changed_strv(bus
,
2101 "/org/freedesktop/systemd1",
2102 "org.freedesktop.systemd1.Manager",
2106 void bus_manager_send_change_signal(Manager
*m
) {
2111 r
= bus_foreach_bus(m
, NULL
, send_changed_signal
, NULL
);
2113 log_debug_errno(r
, "Failed to send manager change signal: %m");