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(sd_bus_message_get_bus(reply
), 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(sd_bus_message_get_bus(reply
), 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
->queued_message_bus
= sd_bus_ref(sd_bus_message_get_bus(message
));
1170 m
->exit_code
= MANAGER_RELOAD
;
1175 static int method_reexecute(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1176 Manager
*m
= userdata
;
1182 r
= mac_selinux_access_check(message
, "reload", error
);
1186 r
= bus_verify_reload_daemon_async(m
, message
, error
);
1190 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1192 /* We don't send a reply back here, the client should
1193 * just wait for us disconnecting. */
1195 m
->exit_code
= MANAGER_REEXECUTE
;
1199 static int method_exit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1200 Manager
*m
= userdata
;
1206 r
= mac_selinux_access_check(message
, "halt", error
);
1210 if (m
->running_as
== SYSTEMD_SYSTEM
)
1211 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Exit is only supported for user service managers.");
1213 m
->exit_code
= MANAGER_EXIT
;
1215 return sd_bus_reply_method_return(message
, NULL
);
1218 static int method_reboot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1219 Manager
*m
= userdata
;
1225 r
= mac_selinux_access_check(message
, "reboot", error
);
1229 if (m
->running_as
!= SYSTEMD_SYSTEM
)
1230 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Reboot is only supported for system managers.");
1232 m
->exit_code
= MANAGER_REBOOT
;
1234 return sd_bus_reply_method_return(message
, NULL
);
1237 static int method_poweroff(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1238 Manager
*m
= userdata
;
1244 r
= mac_selinux_access_check(message
, "halt", error
);
1248 if (m
->running_as
!= SYSTEMD_SYSTEM
)
1249 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Powering off is only supported for system managers.");
1251 m
->exit_code
= MANAGER_POWEROFF
;
1253 return sd_bus_reply_method_return(message
, NULL
);
1256 static int method_halt(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1257 Manager
*m
= userdata
;
1263 r
= mac_selinux_access_check(message
, "halt", error
);
1267 if (m
->running_as
!= SYSTEMD_SYSTEM
)
1268 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Halt is only supported for system managers.");
1270 m
->exit_code
= MANAGER_HALT
;
1272 return sd_bus_reply_method_return(message
, NULL
);
1275 static int method_kexec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1276 Manager
*m
= userdata
;
1282 r
= mac_selinux_access_check(message
, "reboot", error
);
1286 if (m
->running_as
!= SYSTEMD_SYSTEM
)
1287 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "KExec is only supported for system managers.");
1289 m
->exit_code
= MANAGER_KEXEC
;
1291 return sd_bus_reply_method_return(message
, NULL
);
1294 static int method_switch_root(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1295 char *ri
= NULL
, *rt
= NULL
;
1296 const char *root
, *init
;
1297 Manager
*m
= userdata
;
1303 r
= mac_selinux_access_check(message
, "reboot", error
);
1307 if (m
->running_as
!= SYSTEMD_SYSTEM
)
1308 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Root switching is only supported by system manager.");
1310 r
= sd_bus_message_read(message
, "ss", &root
, &init
);
1314 if (path_equal(root
, "/") || !path_is_absolute(root
))
1315 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid switch root path %s", root
);
1318 if (isempty(init
)) {
1319 if (!path_is_os_tree(root
))
1320 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
);
1322 _cleanup_free_
char *p
= NULL
;
1324 if (!path_is_absolute(init
))
1325 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid init path %s", init
);
1327 p
= strappend(root
, init
);
1331 if (access(p
, X_OK
) < 0)
1332 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified init binary %s does not exist.", p
);
1339 if (!isempty(init
)) {
1347 free(m
->switch_root
);
1348 m
->switch_root
= rt
;
1350 free(m
->switch_root_init
);
1351 m
->switch_root_init
= ri
;
1353 m
->exit_code
= MANAGER_SWITCH_ROOT
;
1355 return sd_bus_reply_method_return(message
, NULL
);
1358 static int method_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1359 _cleanup_strv_free_
char **plus
= NULL
;
1360 Manager
*m
= userdata
;
1366 r
= mac_selinux_access_check(message
, "reload", error
);
1370 r
= sd_bus_message_read_strv(message
, &plus
);
1373 if (!strv_env_is_valid(plus
))
1374 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1376 r
= bus_verify_set_environment_async(m
, message
, error
);
1380 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1382 r
= manager_environment_add(m
, NULL
, plus
);
1386 return sd_bus_reply_method_return(message
, NULL
);
1389 static int method_unset_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1390 _cleanup_strv_free_
char **minus
= NULL
;
1391 Manager
*m
= userdata
;
1397 r
= mac_selinux_access_check(message
, "reload", error
);
1401 r
= sd_bus_message_read_strv(message
, &minus
);
1405 if (!strv_env_name_or_assignment_is_valid(minus
))
1406 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1408 r
= bus_verify_set_environment_async(m
, message
, error
);
1412 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1414 r
= manager_environment_add(m
, minus
, NULL
);
1418 return sd_bus_reply_method_return(message
, NULL
);
1421 static int method_unset_and_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1422 _cleanup_strv_free_
char **minus
= NULL
, **plus
= NULL
;
1423 Manager
*m
= userdata
;
1429 r
= mac_selinux_access_check(message
, "reload", error
);
1433 r
= sd_bus_message_read_strv(message
, &minus
);
1437 r
= sd_bus_message_read_strv(message
, &plus
);
1441 if (!strv_env_name_or_assignment_is_valid(minus
))
1442 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1443 if (!strv_env_is_valid(plus
))
1444 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1446 r
= bus_verify_set_environment_async(m
, message
, error
);
1450 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1452 r
= manager_environment_add(m
, minus
, plus
);
1456 return sd_bus_reply_method_return(message
, NULL
);
1459 static int method_list_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1460 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1461 Manager
*m
= userdata
;
1470 /* Anyone can call this method */
1472 r
= mac_selinux_access_check(message
, "status", error
);
1476 r
= sd_bus_message_new_method_return(message
, &reply
);
1480 h
= hashmap_new(&string_hash_ops
);
1484 r
= unit_file_get_list(m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
, NULL
, h
);
1488 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
1492 HASHMAP_FOREACH(item
, h
, i
) {
1494 r
= sd_bus_message_append(reply
, "(ss)", item
->path
, unit_file_state_to_string(item
->state
));
1499 unit_file_list_free(h
);
1501 r
= sd_bus_message_close_container(reply
);
1505 return sd_bus_send(sd_bus_message_get_bus(reply
), reply
, NULL
);
1508 unit_file_list_free(h
);
1512 static int method_get_unit_file_state(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1513 Manager
*m
= userdata
;
1515 UnitFileState state
;
1516 UnitFileScope scope
;
1522 /* Anyone can call this method */
1524 r
= mac_selinux_access_check(message
, "status", error
);
1528 r
= sd_bus_message_read(message
, "s", &name
);
1532 scope
= m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1534 state
= unit_file_get_state(scope
, NULL
, name
);
1538 return sd_bus_reply_method_return(message
, "s", unit_file_state_to_string(state
));
1541 static int method_get_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1542 _cleanup_free_
char *default_target
= NULL
;
1543 Manager
*m
= userdata
;
1544 UnitFileScope scope
;
1550 /* Anyone can call this method */
1552 r
= mac_selinux_access_check(message
, "status", error
);
1556 scope
= m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1558 r
= unit_file_get_default(scope
, NULL
, &default_target
);
1562 return sd_bus_reply_method_return(message
, "s", default_target
);
1565 static int send_unit_files_changed(sd_bus
*bus
, void *userdata
) {
1566 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
1571 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1575 return sd_bus_send(bus
, message
, NULL
);
1578 static int reply_unit_file_changes_and_free(
1580 sd_bus_message
*message
,
1581 int carries_install_info
,
1582 UnitFileChange
*changes
,
1583 unsigned n_changes
) {
1585 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1589 if (n_changes
> 0) {
1590 r
= bus_foreach_bus(m
, NULL
, send_unit_files_changed
, NULL
);
1592 log_debug_errno(r
, "Failed to send UnitFilesChanged signal: %m");
1595 r
= sd_bus_message_new_method_return(message
, &reply
);
1599 if (carries_install_info
>= 0) {
1600 r
= sd_bus_message_append(reply
, "b", carries_install_info
);
1605 r
= sd_bus_message_open_container(reply
, 'a', "(sss)");
1609 for (i
= 0; i
< n_changes
; i
++) {
1610 r
= sd_bus_message_append(
1612 unit_file_change_type_to_string(changes
[i
].type
),
1619 r
= sd_bus_message_close_container(reply
);
1623 return sd_bus_send(sd_bus_message_get_bus(message
), reply
, NULL
);
1626 unit_file_changes_free(changes
, n_changes
);
1630 static int method_enable_unit_files_generic(
1631 sd_bus_message
*message
,
1634 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], bool force
, UnitFileChange
**changes
, unsigned *n_changes
),
1635 bool carries_install_info
,
1636 sd_bus_error
*error
) {
1638 _cleanup_strv_free_
char **l
= NULL
;
1639 UnitFileChange
*changes
= NULL
;
1640 unsigned n_changes
= 0;
1641 UnitFileScope scope
;
1642 int runtime
, force
, r
;
1647 r
= sd_bus_message_read_strv(message
, &l
);
1651 r
= sd_bus_message_read(message
, "bb", &runtime
, &force
);
1655 r
= mac_selinux_unit_access_check_strv(l
, message
, m
, verb
, error
);
1659 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1663 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1665 scope
= m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1667 r
= call(scope
, runtime
, NULL
, l
, force
, &changes
, &n_changes
);
1671 return reply_unit_file_changes_and_free(m
, message
, carries_install_info
? r
: -1, changes
, n_changes
);
1674 static int method_enable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1675 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_enable
, true, error
);
1678 static int method_reenable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1679 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_reenable
, true, error
);
1682 static int method_link_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1683 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_link
, false, error
);
1686 static int unit_file_preset_without_mode(UnitFileScope scope
, bool runtime
, const char *root_dir
, char **files
, bool force
, UnitFileChange
**changes
, unsigned *n_changes
) {
1687 return unit_file_preset(scope
, runtime
, root_dir
, files
, UNIT_FILE_PRESET_FULL
, force
, changes
, n_changes
);
1690 static int method_preset_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1691 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_preset_without_mode
, true, error
);
1694 static int method_mask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1695 return method_enable_unit_files_generic(message
, userdata
, "disable", unit_file_mask
, false, error
);
1698 static int method_preset_unit_files_with_mode(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1700 _cleanup_strv_free_
char **l
= NULL
;
1701 UnitFileChange
*changes
= NULL
;
1702 unsigned n_changes
= 0;
1703 Manager
*m
= userdata
;
1704 UnitFilePresetMode mm
;
1705 UnitFileScope scope
;
1706 int runtime
, force
, r
;
1712 r
= sd_bus_message_read_strv(message
, &l
);
1716 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1721 mm
= UNIT_FILE_PRESET_FULL
;
1723 mm
= unit_file_preset_mode_from_string(mode
);
1728 r
= mac_selinux_unit_access_check_strv(l
, message
, m
, "enable", error
);
1732 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1736 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1738 scope
= m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1740 r
= unit_file_preset(scope
, runtime
, NULL
, l
, mm
, force
, &changes
, &n_changes
);
1744 return reply_unit_file_changes_and_free(m
, message
, r
, changes
, n_changes
);
1747 static int method_disable_unit_files_generic(
1748 sd_bus_message
*message
,
1751 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], UnitFileChange
**changes
, unsigned *n_changes
),
1752 sd_bus_error
*error
) {
1754 _cleanup_strv_free_
char **l
= NULL
;
1755 UnitFileChange
*changes
= NULL
;
1756 unsigned n_changes
= 0;
1757 UnitFileScope scope
;
1763 r
= sd_bus_message_read_strv(message
, &l
);
1767 r
= sd_bus_message_read(message
, "b", &runtime
);
1771 r
= mac_selinux_unit_access_check_strv(l
, message
, m
, verb
, error
);
1775 scope
= m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1777 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1781 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1783 r
= call(scope
, runtime
, NULL
, l
, &changes
, &n_changes
);
1787 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1790 static int method_disable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1791 return method_disable_unit_files_generic(message
, userdata
, "disable", unit_file_disable
, error
);
1794 static int method_unmask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1795 return method_disable_unit_files_generic(message
, userdata
, "enable", unit_file_unmask
, error
);
1798 static int method_set_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1799 UnitFileChange
*changes
= NULL
;
1800 unsigned n_changes
= 0;
1801 Manager
*m
= userdata
;
1802 UnitFileScope scope
;
1809 r
= mac_selinux_access_check(message
, "enable", error
);
1813 r
= sd_bus_message_read(message
, "sb", &name
, &force
);
1817 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1821 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1823 scope
= m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1825 r
= unit_file_set_default(scope
, NULL
, name
, force
, &changes
, &n_changes
);
1829 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1832 static int method_preset_all_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1833 UnitFileChange
*changes
= NULL
;
1834 unsigned n_changes
= 0;
1835 Manager
*m
= userdata
;
1836 UnitFilePresetMode mm
;
1837 UnitFileScope scope
;
1839 int force
, runtime
, r
;
1844 r
= mac_selinux_access_check(message
, "enable", error
);
1848 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1853 mm
= UNIT_FILE_PRESET_FULL
;
1855 mm
= unit_file_preset_mode_from_string(mode
);
1860 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1864 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1866 scope
= m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1868 r
= unit_file_preset_all(scope
, runtime
, NULL
, mm
, force
, &changes
, &n_changes
);
1872 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1875 static int method_add_dependency_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1876 _cleanup_strv_free_
char **l
= NULL
;
1877 Manager
*m
= userdata
;
1878 UnitFileChange
*changes
= NULL
;
1879 unsigned n_changes
= 0;
1880 UnitFileScope scope
;
1881 int runtime
, force
, r
;
1889 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1893 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1895 r
= sd_bus_message_read_strv(message
, &l
);
1899 r
= sd_bus_message_read(message
, "ssbb", &target
, &type
, &runtime
, &force
);
1903 dep
= unit_dependency_from_string(type
);
1907 r
= mac_selinux_unit_access_check_strv(l
, message
, m
, "enable", error
);
1911 scope
= m
->running_as
== SYSTEMD_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1913 r
= unit_file_add_dependency(scope
, runtime
, NULL
, l
, target
, dep
, force
, &changes
, &n_changes
);
1917 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1920 const sd_bus_vtable bus_manager_vtable
[] = {
1921 SD_BUS_VTABLE_START(0),
1923 SD_BUS_PROPERTY("Version", "s", property_get_version
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1924 SD_BUS_PROPERTY("Features", "s", property_get_features
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1925 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1926 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1927 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1928 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager
, firmware_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1929 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager
, loader_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1930 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager
, kernel_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1931 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager
, initrd_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1932 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager
, userspace_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1933 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager
, finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1934 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager
, security_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1935 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager
, security_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1936 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager
, generators_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1937 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager
, generators_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1938 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager
, units_load_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1939 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager
, units_load_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1940 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level
, property_set_log_level
, 0, 0),
1941 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target
, property_set_log_target
, 0, 0),
1942 SD_BUS_PROPERTY("NNames", "u", property_get_n_names
, 0, 0),
1943 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1944 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs
, 0, 0),
1945 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_installed_jobs
), 0),
1946 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_failed_jobs
), 0),
1947 SD_BUS_PROPERTY("Progress", "d", property_get_progress
, 0, 0),
1948 SD_BUS_PROPERTY("Environment", "as", NULL
, offsetof(Manager
, environment
), 0),
1949 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool
, offsetof(Manager
, confirm_spawn
), SD_BUS_VTABLE_PROPERTY_CONST
),
1950 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool
, offsetof(Manager
, show_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
1951 SD_BUS_PROPERTY("UnitPath", "as", NULL
, offsetof(Manager
, lookup_paths
.unit_path
), SD_BUS_VTABLE_PROPERTY_CONST
),
1952 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1953 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1954 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec
, property_set_runtime_watchdog
, offsetof(Manager
, runtime_watchdog
), 0),
1955 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec
, bus_property_set_usec
, offsetof(Manager
, shutdown_watchdog
), 0),
1956 SD_BUS_PROPERTY("ControlGroup", "s", NULL
, offsetof(Manager
, cgroup_root
), 0),
1957 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state
, 0, 0),
1959 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1960 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid
, SD_BUS_VTABLE_UNPRIVILEGED
),
1961 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1962 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1963 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace
, SD_BUS_VTABLE_UNPRIVILEGED
),
1964 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1965 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1966 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1967 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1968 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1969 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1970 SD_BUS_METHOD("KillUnit", "ssi", NULL
, method_kill_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1971 SD_BUS_METHOD("ResetFailedUnit", "s", NULL
, method_reset_failed_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1972 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL
, method_set_unit_properties
, SD_BUS_VTABLE_UNPRIVILEGED
),
1973 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1974 SD_BUS_METHOD("GetJob", "u", "o", method_get_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
1975 SD_BUS_METHOD("CancelJob", "u", NULL
, method_cancel_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
1976 SD_BUS_METHOD("ClearJobs", NULL
, NULL
, method_clear_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
1977 SD_BUS_METHOD("ResetFailed", NULL
, NULL
, method_reset_failed
, SD_BUS_VTABLE_UNPRIVILEGED
),
1978 SD_BUS_METHOD("ListUnits", NULL
, "a(ssssssouso)", method_list_units
, SD_BUS_VTABLE_UNPRIVILEGED
),
1979 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered
, SD_BUS_VTABLE_UNPRIVILEGED
),
1980 SD_BUS_METHOD("ListJobs", NULL
, "a(usssoo)", method_list_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
1981 SD_BUS_METHOD("Subscribe", NULL
, NULL
, method_subscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
1982 SD_BUS_METHOD("Unsubscribe", NULL
, NULL
, method_unsubscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
1983 SD_BUS_METHOD("Dump", NULL
, "s", method_dump
, SD_BUS_VTABLE_UNPRIVILEGED
),
1984 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
1985 SD_BUS_METHOD("RemoveSnapshot", "s", NULL
, method_remove_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
1986 SD_BUS_METHOD("Reload", NULL
, NULL
, method_reload
, SD_BUS_VTABLE_UNPRIVILEGED
),
1987 SD_BUS_METHOD("Reexecute", NULL
, NULL
, method_reexecute
, SD_BUS_VTABLE_UNPRIVILEGED
),
1988 SD_BUS_METHOD("Exit", NULL
, NULL
, method_exit
, 0),
1989 SD_BUS_METHOD("Reboot", NULL
, NULL
, method_reboot
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1990 SD_BUS_METHOD("PowerOff", NULL
, NULL
, method_poweroff
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1991 SD_BUS_METHOD("Halt", NULL
, NULL
, method_halt
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1992 SD_BUS_METHOD("KExec", NULL
, NULL
, method_kexec
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1993 SD_BUS_METHOD("SwitchRoot", "ss", NULL
, method_switch_root
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1994 SD_BUS_METHOD("SetEnvironment", "as", NULL
, method_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1995 SD_BUS_METHOD("UnsetEnvironment", "as", NULL
, method_unset_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1996 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL
, method_unset_and_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1997 SD_BUS_METHOD("ListUnitFiles", NULL
, "a(ss)", method_list_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1998 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state
, SD_BUS_VTABLE_UNPRIVILEGED
),
1999 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2000 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2001 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2002 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2003 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2004 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode
, SD_BUS_VTABLE_UNPRIVILEGED
),
2005 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2006 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2007 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
2008 SD_BUS_METHOD("GetDefaultTarget", NULL
, "s", method_get_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
2009 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2010 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2012 SD_BUS_SIGNAL("UnitNew", "so", 0),
2013 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2014 SD_BUS_SIGNAL("JobNew", "uos", 0),
2015 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2016 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2017 SD_BUS_SIGNAL("UnitFilesChanged", NULL
, 0),
2018 SD_BUS_SIGNAL("Reloading", "b", 0),
2023 static int send_finished(sd_bus
*bus
, void *userdata
) {
2024 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2025 usec_t
*times
= userdata
;
2031 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2035 r
= sd_bus_message_append(message
, "tttttt", times
[0], times
[1], times
[2], times
[3], times
[4], times
[5]);
2039 return sd_bus_send(bus
, message
, NULL
);
2042 void bus_manager_send_finished(
2044 usec_t firmware_usec
,
2048 usec_t userspace_usec
,
2049 usec_t total_usec
) {
2055 r
= bus_foreach_bus(
2068 log_debug_errno(r
, "Failed to send finished signal: %m");
2071 static int send_reloading(sd_bus
*bus
, void *userdata
) {
2072 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2077 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2081 r
= sd_bus_message_append(message
, "b", PTR_TO_INT(userdata
));
2085 return sd_bus_send(bus
, message
, NULL
);
2088 void bus_manager_send_reloading(Manager
*m
, bool active
) {
2093 r
= bus_foreach_bus(m
, NULL
, send_reloading
, INT_TO_PTR(active
));
2095 log_debug_errno(r
, "Failed to send reloading signal: %m");
2098 static int send_changed_signal(sd_bus
*bus
, void *userdata
) {
2101 return sd_bus_emit_properties_changed_strv(bus
,
2102 "/org/freedesktop/systemd1",
2103 "org.freedesktop.systemd1.Manager",
2107 void bus_manager_send_change_signal(Manager
*m
) {
2112 r
= bus_foreach_bus(m
, NULL
, send_changed_signal
, NULL
);
2114 log_debug_errno(r
, "Failed to send manager change signal: %m");