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
) {
87 return sd_bus_message_append(reply
, "s", virtualization_to_string(detect_virtualization()));
90 static int property_get_architecture(
93 const char *interface
,
95 sd_bus_message
*reply
,
97 sd_bus_error
*error
) {
102 return sd_bus_message_append(reply
, "s", architecture_to_string(uname_architecture()));
105 static int property_get_tainted(
108 const char *interface
,
109 const char *property
,
110 sd_bus_message
*reply
,
112 sd_bus_error
*error
) {
114 char buf
[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e
= buf
;
115 _cleanup_free_
char *p
= NULL
;
116 Manager
*m
= userdata
;
123 e
= stpcpy(e
, "split-usr:");
125 if (readlink_malloc("/etc/mtab", &p
) < 0)
126 e
= stpcpy(e
, "mtab-not-symlink:");
128 if (access("/proc/cgroups", F_OK
) < 0)
129 e
= stpcpy(e
, "cgroups-missing:");
131 if (clock_is_localtime() > 0)
132 e
= stpcpy(e
, "local-hwclock:");
134 /* remove the last ':' */
138 return sd_bus_message_append(reply
, "s", buf
);
141 static int property_get_log_target(
144 const char *interface
,
145 const char *property
,
146 sd_bus_message
*reply
,
148 sd_bus_error
*error
) {
153 return sd_bus_message_append(reply
, "s", log_target_to_string(log_get_target()));
156 static int property_set_log_target(
159 const char *interface
,
160 const char *property
,
161 sd_bus_message
*value
,
163 sd_bus_error
*error
) {
171 r
= sd_bus_message_read(value
, "s", &t
);
175 return log_set_target_from_string(t
);
178 static int property_get_log_level(
181 const char *interface
,
182 const char *property
,
183 sd_bus_message
*reply
,
185 sd_bus_error
*error
) {
187 _cleanup_free_
char *t
= NULL
;
193 r
= log_level_to_string_alloc(log_get_max_level(), &t
);
197 return sd_bus_message_append(reply
, "s", t
);
200 static int property_set_log_level(
203 const char *interface
,
204 const char *property
,
205 sd_bus_message
*value
,
207 sd_bus_error
*error
) {
215 r
= sd_bus_message_read(value
, "s", &t
);
219 return log_set_max_level_from_string(t
);
222 static int property_get_n_names(
225 const char *interface
,
226 const char *property
,
227 sd_bus_message
*reply
,
229 sd_bus_error
*error
) {
231 Manager
*m
= userdata
;
237 return sd_bus_message_append(reply
, "u", (uint32_t) hashmap_size(m
->units
));
240 static int property_get_n_failed_units(
243 const char *interface
,
244 const char *property
,
245 sd_bus_message
*reply
,
247 sd_bus_error
*error
) {
249 Manager
*m
= userdata
;
255 return sd_bus_message_append(reply
, "u", (uint32_t) set_size(m
->failed_units
));
258 static int property_get_n_jobs(
261 const char *interface
,
262 const char *property
,
263 sd_bus_message
*reply
,
265 sd_bus_error
*error
) {
267 Manager
*m
= userdata
;
273 return sd_bus_message_append(reply
, "u", (uint32_t) hashmap_size(m
->jobs
));
276 static int property_get_progress(
279 const char *interface
,
280 const char *property
,
281 sd_bus_message
*reply
,
283 sd_bus_error
*error
) {
285 Manager
*m
= userdata
;
292 if (dual_timestamp_is_set(&m
->finish_timestamp
))
295 d
= 1.0 - ((double) hashmap_size(m
->jobs
) / (double) m
->n_installed_jobs
);
297 return sd_bus_message_append(reply
, "d", d
);
300 static int property_get_system_state(
303 const char *interface
,
304 const char *property
,
305 sd_bus_message
*reply
,
307 sd_bus_error
*error
) {
309 Manager
*m
= userdata
;
315 return sd_bus_message_append(reply
, "s", manager_state_to_string(manager_state(m
)));
318 static int property_set_runtime_watchdog(
321 const char *interface
,
322 const char *property
,
323 sd_bus_message
*value
,
325 sd_bus_error
*error
) {
327 usec_t
*t
= userdata
;
333 assert_cc(sizeof(usec_t
) == sizeof(uint64_t));
335 r
= sd_bus_message_read(value
, "t", t
);
339 return watchdog_set_timeout(t
);
342 static int method_get_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
343 _cleanup_free_
char *path
= NULL
;
344 Manager
*m
= userdata
;
352 /* Anyone can call this method */
354 r
= sd_bus_message_read(message
, "s", &name
);
359 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
362 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
366 r
= sd_bus_creds_get_pid(creds
, &pid
);
370 u
= manager_get_unit_by_pid(m
, pid
);
372 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Client not member of any unit.");
374 u
= manager_get_unit(m
, name
);
376 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s not loaded.", name
);
379 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
383 path
= unit_dbus_path(u
);
387 return sd_bus_reply_method_return(message
, "o", path
);
390 static int method_get_unit_by_pid(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
391 _cleanup_free_
char *path
= NULL
;
392 Manager
*m
= userdata
;
400 assert_cc(sizeof(pid_t
) == sizeof(uint32_t));
402 /* Anyone can call this method */
404 r
= sd_bus_message_read(message
, "u", &pid
);
408 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid PID " PID_FMT
, pid
);
411 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
413 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
417 r
= sd_bus_creds_get_pid(creds
, &pid
);
422 u
= manager_get_unit_by_pid(m
, pid
);
424 return sd_bus_error_setf(error
, BUS_ERROR_NO_UNIT_FOR_PID
, "PID "PID_FMT
" does not belong to any loaded unit.", pid
);
426 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
430 path
= unit_dbus_path(u
);
434 return sd_bus_reply_method_return(message
, "o", path
);
437 static int method_load_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
438 _cleanup_free_
char *path
= NULL
;
439 Manager
*m
= userdata
;
447 /* Anyone can call this method */
449 r
= sd_bus_message_read(message
, "s", &name
);
454 _cleanup_bus_creds_unref_ sd_bus_creds
*creds
= NULL
;
457 r
= sd_bus_query_sender_creds(message
, SD_BUS_CREDS_PID
, &creds
);
461 r
= sd_bus_creds_get_pid(creds
, &pid
);
465 u
= manager_get_unit_by_pid(m
, pid
);
467 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Client not member of any unit.");
469 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
474 r
= mac_selinux_unit_access_check(u
, message
, "status", error
);
478 path
= unit_dbus_path(u
);
482 return sd_bus_reply_method_return(message
, "o", path
);
485 static int method_start_unit_generic(sd_bus_message
*message
, Manager
*m
, JobType job_type
, bool reload_if_possible
, sd_bus_error
*error
) {
493 r
= sd_bus_message_read(message
, "s", &name
);
497 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
501 return bus_unit_method_start_generic(message
, u
, job_type
, reload_if_possible
, error
);
504 static int method_start_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
505 return method_start_unit_generic(message
, userdata
, JOB_START
, false, error
);
508 static int method_stop_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
509 return method_start_unit_generic(message
, userdata
, JOB_STOP
, false, error
);
512 static int method_reload_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
513 return method_start_unit_generic(message
, userdata
, JOB_RELOAD
, false, error
);
516 static int method_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
517 return method_start_unit_generic(message
, userdata
, JOB_RESTART
, false, error
);
520 static int method_try_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
521 return method_start_unit_generic(message
, userdata
, JOB_TRY_RESTART
, false, error
);
524 static int method_reload_or_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
525 return method_start_unit_generic(message
, userdata
, JOB_RESTART
, true, error
);
528 static int method_reload_or_try_restart_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
529 return method_start_unit_generic(message
, userdata
, JOB_TRY_RESTART
, true, error
);
532 static int method_start_unit_replace(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
533 Manager
*m
= userdata
;
534 const char *old_name
;
541 r
= sd_bus_message_read(message
, "s", &old_name
);
545 u
= manager_get_unit(m
, old_name
);
546 if (!u
|| !u
->job
|| u
->job
->type
!= JOB_START
)
547 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "No job queued for unit %s", old_name
);
549 return method_start_unit_generic(message
, m
, JOB_START
, false, error
);
552 static int method_kill_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
553 Manager
*m
= userdata
;
561 r
= sd_bus_message_read(message
, "s", &name
);
565 u
= manager_get_unit(m
, name
);
567 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
569 return bus_unit_method_kill(message
, u
, error
);
572 static int method_reset_failed_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
573 Manager
*m
= userdata
;
581 r
= sd_bus_message_read(message
, "s", &name
);
585 u
= manager_get_unit(m
, name
);
587 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
589 return bus_unit_method_reset_failed(message
, u
, error
);
592 static int method_set_unit_properties(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
593 Manager
*m
= userdata
;
601 r
= sd_bus_message_read(message
, "s", &name
);
605 u
= manager_get_unit(m
, name
);
607 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not loaded.", name
);
609 return bus_unit_method_set_properties(message
, u
, error
);
612 static int transient_unit_from_message(
614 sd_bus_message
*message
,
617 sd_bus_error
*error
) {
626 r
= manager_load_unit(m
, name
, NULL
, error
, &u
);
630 if (u
->load_state
!= UNIT_NOT_FOUND
||
631 set_size(u
->dependencies
[UNIT_REFERENCED_BY
]) > 0)
632 return sd_bus_error_setf(error
, BUS_ERROR_UNIT_EXISTS
, "Unit %s already exists.", name
);
634 /* OK, the unit failed to load and is unreferenced, now let's
635 * fill in the transient data instead */
636 r
= unit_make_transient(u
);
640 /* Set our properties */
641 r
= bus_unit_set_properties(u
, message
, UNIT_RUNTIME
, false, error
);
650 static int transient_aux_units_from_message(
652 sd_bus_message
*message
,
653 sd_bus_error
*error
) {
662 r
= sd_bus_message_enter_container(message
, 'a', "(sa(sv))");
666 while ((r
= sd_bus_message_enter_container(message
, 'r', "sa(sv)")) > 0) {
667 r
= sd_bus_message_read(message
, "s", &name
);
671 r
= transient_unit_from_message(m
, message
, name
, &u
, error
);
672 if (r
< 0 && r
!= -EEXIST
)
681 r
= sd_bus_message_exit_container(message
);
688 r
= sd_bus_message_exit_container(message
);
695 static int method_start_transient_unit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
696 const char *name
, *smode
;
697 Manager
*m
= userdata
;
706 r
= mac_selinux_access_check(message
, "start", error
);
710 r
= sd_bus_message_read(message
, "ss", &name
, &smode
);
714 t
= unit_name_to_type(name
);
716 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid unit type.");
718 if (!unit_vtable
[t
]->can_transient
)
719 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unit type %s does not support transient units.", unit_type_to_string(t
));
721 mode
= job_mode_from_string(smode
);
723 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Job mode %s is invalid.", smode
);
725 r
= bus_verify_manage_units_async(m
, message
, error
);
729 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
731 r
= transient_unit_from_message(m
, message
, name
, &u
, error
);
735 r
= transient_aux_units_from_message(m
, message
, error
);
739 /* And load this stub fully */
744 manager_dispatch_load_queue(m
);
746 /* Finally, start it */
747 return bus_unit_queue_job(message
, u
, JOB_START
, mode
, false, error
);
750 static int method_get_job(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
751 _cleanup_free_
char *path
= NULL
;
752 Manager
*m
= userdata
;
760 /* Anyone can call this method */
762 r
= sd_bus_message_read(message
, "u", &id
);
766 j
= manager_get_job(m
, id
);
768 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "Job %u does not exist.", (unsigned) id
);
770 r
= mac_selinux_unit_access_check(j
->unit
, message
, "status", error
);
774 path
= job_dbus_path(j
);
778 return sd_bus_reply_method_return(message
, "o", path
);
781 static int method_cancel_job(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
782 Manager
*m
= userdata
;
790 r
= sd_bus_message_read(message
, "u", &id
);
794 j
= manager_get_job(m
, id
);
796 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_JOB
, "Job %u does not exist.", (unsigned) id
);
798 return bus_job_method_cancel(message
, j
, error
);
801 static int method_clear_jobs(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
802 Manager
*m
= userdata
;
808 r
= mac_selinux_access_check(message
, "reload", error
);
812 r
= bus_verify_manage_units_async(m
, message
, error
);
816 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
818 manager_clear_jobs(m
);
820 return sd_bus_reply_method_return(message
, NULL
);
823 static int method_reset_failed(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
824 Manager
*m
= userdata
;
830 r
= mac_selinux_access_check(message
, "reload", error
);
834 r
= bus_verify_manage_units_async(m
, message
, error
);
838 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
840 manager_reset_failed(m
);
842 return sd_bus_reply_method_return(message
, NULL
);
845 static int list_units_filtered(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
, char **states
) {
846 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
847 Manager
*m
= userdata
;
856 /* Anyone can call this method */
858 r
= mac_selinux_access_check(message
, "status", error
);
862 r
= sd_bus_message_new_method_return(message
, &reply
);
866 r
= sd_bus_message_open_container(reply
, 'a', "(ssssssouso)");
870 HASHMAP_FOREACH_KEY(u
, k
, m
->units
, i
) {
871 _cleanup_free_
char *unit_path
= NULL
, *job_path
= NULL
;
877 following
= unit_following(u
);
879 if (!strv_isempty(states
) &&
880 !strv_contains(states
, unit_load_state_to_string(u
->load_state
)) &&
881 !strv_contains(states
, unit_active_state_to_string(unit_active_state(u
))) &&
882 !strv_contains(states
, unit_sub_state_to_string(u
)))
885 unit_path
= unit_dbus_path(u
);
890 job_path
= job_dbus_path(u
->job
);
895 r
= sd_bus_message_append(
896 reply
, "(ssssssouso)",
899 unit_load_state_to_string(u
->load_state
),
900 unit_active_state_to_string(unit_active_state(u
)),
901 unit_sub_state_to_string(u
),
902 following
? following
->id
: "",
904 u
->job
? u
->job
->id
: 0,
905 u
->job
? job_type_to_string(u
->job
->type
) : "",
906 job_path
? job_path
: "/");
911 r
= sd_bus_message_close_container(reply
);
915 return sd_bus_send(NULL
, reply
, NULL
);
918 static int method_list_units(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
919 return list_units_filtered(message
, userdata
, error
, NULL
);
922 static int method_list_units_filtered(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
923 _cleanup_strv_free_
char **states
= NULL
;
926 r
= sd_bus_message_read_strv(message
, &states
);
930 return list_units_filtered(message
, userdata
, error
, states
);
933 static int method_list_jobs(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
934 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
935 Manager
*m
= userdata
;
943 /* Anyone can call this method */
945 r
= mac_selinux_access_check(message
, "status", error
);
949 r
= sd_bus_message_new_method_return(message
, &reply
);
953 r
= sd_bus_message_open_container(reply
, 'a', "(usssoo)");
957 HASHMAP_FOREACH(j
, m
->jobs
, i
) {
958 _cleanup_free_
char *unit_path
= NULL
, *job_path
= NULL
;
960 job_path
= job_dbus_path(j
);
964 unit_path
= unit_dbus_path(j
->unit
);
968 r
= sd_bus_message_append(
972 job_type_to_string(j
->type
),
973 job_state_to_string(j
->state
),
980 r
= sd_bus_message_close_container(reply
);
984 return sd_bus_send(NULL
, reply
, NULL
);
987 static int method_subscribe(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
988 Manager
*m
= userdata
;
994 /* Anyone can call this method */
996 r
= mac_selinux_access_check(message
, "status", error
);
1000 if (sd_bus_message_get_bus(message
) == m
->api_bus
) {
1002 /* Note that direct bus connection subscribe by
1003 * default, we only track peers on the API bus here */
1005 if (!m
->subscribed
) {
1006 r
= sd_bus_track_new(sd_bus_message_get_bus(message
), &m
->subscribed
, NULL
, NULL
);
1011 r
= sd_bus_track_add_sender(m
->subscribed
, message
);
1015 return sd_bus_error_setf(error
, BUS_ERROR_ALREADY_SUBSCRIBED
, "Client is already subscribed.");
1018 return sd_bus_reply_method_return(message
, NULL
);
1021 static int method_unsubscribe(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1022 Manager
*m
= userdata
;
1028 /* Anyone can call this method */
1030 r
= mac_selinux_access_check(message
, "status", error
);
1034 if (sd_bus_message_get_bus(message
) == m
->api_bus
) {
1035 r
= sd_bus_track_remove_sender(m
->subscribed
, message
);
1039 return sd_bus_error_setf(error
, BUS_ERROR_NOT_SUBSCRIBED
, "Client is not subscribed.");
1042 return sd_bus_reply_method_return(message
, NULL
);
1045 static int method_dump(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1046 _cleanup_free_
char *dump
= NULL
;
1047 _cleanup_fclose_
FILE *f
= NULL
;
1048 Manager
*m
= userdata
;
1055 /* Anyone can call this method */
1057 r
= mac_selinux_access_check(message
, "status", error
);
1061 f
= open_memstream(&dump
, &size
);
1065 manager_dump_units(m
, f
, NULL
);
1066 manager_dump_jobs(m
, f
, NULL
);
1068 r
= fflush_and_check(f
);
1072 return sd_bus_reply_method_return(message
, "s", dump
);
1075 static int method_create_snapshot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1076 _cleanup_free_
char *path
= NULL
;
1077 Manager
*m
= userdata
;
1086 r
= mac_selinux_access_check(message
, "start", error
);
1090 r
= sd_bus_message_read(message
, "sb", &name
, &cleanup
);
1097 r
= bus_verify_manage_units_async(m
, message
, error
);
1101 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1103 r
= snapshot_create(m
, name
, cleanup
, error
, &s
);
1107 path
= unit_dbus_path(UNIT(s
));
1111 return sd_bus_reply_method_return(message
, "o", path
);
1114 static int method_remove_snapshot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1115 Manager
*m
= userdata
;
1123 r
= sd_bus_message_read(message
, "s", &name
);
1127 u
= manager_get_unit(m
, name
);
1129 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s does not exist.", name
);
1131 if (u
->type
!= UNIT_SNAPSHOT
)
1132 return sd_bus_error_setf(error
, BUS_ERROR_NO_SUCH_UNIT
, "Unit %s is not a snapshot", name
);
1134 return bus_snapshot_method_remove(message
, u
, error
);
1137 static int method_reload(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1138 Manager
*m
= userdata
;
1144 r
= mac_selinux_access_check(message
, "reload", error
);
1148 r
= bus_verify_reload_daemon_async(m
, message
, error
);
1152 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1154 /* Instead of sending the reply back right away, we just
1155 * remember that we need to and then send it after the reload
1156 * is finished. That way the caller knows when the reload
1159 assert(!m
->queued_message
);
1160 r
= sd_bus_message_new_method_return(message
, &m
->queued_message
);
1164 m
->exit_code
= MANAGER_RELOAD
;
1169 static int method_reexecute(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1170 Manager
*m
= userdata
;
1176 r
= mac_selinux_access_check(message
, "reload", error
);
1180 r
= bus_verify_reload_daemon_async(m
, message
, error
);
1184 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1186 /* We don't send a reply back here, the client should
1187 * just wait for us disconnecting. */
1189 m
->exit_code
= MANAGER_REEXECUTE
;
1193 static int method_exit(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1194 Manager
*m
= userdata
;
1200 r
= mac_selinux_access_check(message
, "halt", error
);
1204 if (m
->running_as
== MANAGER_SYSTEM
)
1205 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Exit is only supported for user service managers.");
1207 m
->exit_code
= MANAGER_EXIT
;
1209 return sd_bus_reply_method_return(message
, NULL
);
1212 static int method_reboot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1213 Manager
*m
= userdata
;
1219 r
= mac_selinux_access_check(message
, "reboot", error
);
1223 if (m
->running_as
!= MANAGER_SYSTEM
)
1224 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Reboot is only supported for system managers.");
1226 m
->exit_code
= MANAGER_REBOOT
;
1228 return sd_bus_reply_method_return(message
, NULL
);
1231 static int method_poweroff(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1232 Manager
*m
= userdata
;
1238 r
= mac_selinux_access_check(message
, "halt", error
);
1242 if (m
->running_as
!= MANAGER_SYSTEM
)
1243 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Powering off is only supported for system managers.");
1245 m
->exit_code
= MANAGER_POWEROFF
;
1247 return sd_bus_reply_method_return(message
, NULL
);
1250 static int method_halt(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1251 Manager
*m
= userdata
;
1257 r
= mac_selinux_access_check(message
, "halt", error
);
1261 if (m
->running_as
!= MANAGER_SYSTEM
)
1262 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Halt is only supported for system managers.");
1264 m
->exit_code
= MANAGER_HALT
;
1266 return sd_bus_reply_method_return(message
, NULL
);
1269 static int method_kexec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1270 Manager
*m
= userdata
;
1276 r
= mac_selinux_access_check(message
, "reboot", error
);
1280 if (m
->running_as
!= MANAGER_SYSTEM
)
1281 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "KExec is only supported for system managers.");
1283 m
->exit_code
= MANAGER_KEXEC
;
1285 return sd_bus_reply_method_return(message
, NULL
);
1288 static int method_switch_root(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1289 char *ri
= NULL
, *rt
= NULL
;
1290 const char *root
, *init
;
1291 Manager
*m
= userdata
;
1297 r
= mac_selinux_access_check(message
, "reboot", error
);
1301 if (m
->running_as
!= MANAGER_SYSTEM
)
1302 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Root switching is only supported by system manager.");
1304 r
= sd_bus_message_read(message
, "ss", &root
, &init
);
1308 if (path_equal(root
, "/") || !path_is_absolute(root
))
1309 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid switch root path %s", root
);
1312 if (isempty(init
)) {
1313 if (!path_is_os_tree(root
))
1314 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
);
1316 _cleanup_free_
char *p
= NULL
;
1318 if (!path_is_absolute(init
))
1319 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid init path %s", init
);
1321 p
= strappend(root
, init
);
1325 if (access(p
, X_OK
) < 0)
1326 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified init binary %s does not exist.", p
);
1333 if (!isempty(init
)) {
1341 free(m
->switch_root
);
1342 m
->switch_root
= rt
;
1344 free(m
->switch_root_init
);
1345 m
->switch_root_init
= ri
;
1347 m
->exit_code
= MANAGER_SWITCH_ROOT
;
1349 return sd_bus_reply_method_return(message
, NULL
);
1352 static int method_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1353 _cleanup_strv_free_
char **plus
= NULL
;
1354 Manager
*m
= userdata
;
1360 r
= mac_selinux_access_check(message
, "reload", error
);
1364 r
= sd_bus_message_read_strv(message
, &plus
);
1367 if (!strv_env_is_valid(plus
))
1368 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1370 r
= bus_verify_set_environment_async(m
, message
, error
);
1374 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1376 r
= manager_environment_add(m
, NULL
, plus
);
1380 return sd_bus_reply_method_return(message
, NULL
);
1383 static int method_unset_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1384 _cleanup_strv_free_
char **minus
= NULL
;
1385 Manager
*m
= userdata
;
1391 r
= mac_selinux_access_check(message
, "reload", error
);
1395 r
= sd_bus_message_read_strv(message
, &minus
);
1399 if (!strv_env_name_or_assignment_is_valid(minus
))
1400 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1402 r
= bus_verify_set_environment_async(m
, message
, error
);
1406 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1408 r
= manager_environment_add(m
, minus
, NULL
);
1412 return sd_bus_reply_method_return(message
, NULL
);
1415 static int method_unset_and_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1416 _cleanup_strv_free_
char **minus
= NULL
, **plus
= NULL
;
1417 Manager
*m
= userdata
;
1423 r
= mac_selinux_access_check(message
, "reload", error
);
1427 r
= sd_bus_message_read_strv(message
, &minus
);
1431 r
= sd_bus_message_read_strv(message
, &plus
);
1435 if (!strv_env_name_or_assignment_is_valid(minus
))
1436 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1437 if (!strv_env_is_valid(plus
))
1438 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1440 r
= bus_verify_set_environment_async(m
, message
, error
);
1444 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1446 r
= manager_environment_add(m
, minus
, plus
);
1450 return sd_bus_reply_method_return(message
, NULL
);
1453 static int method_list_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1454 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1455 Manager
*m
= userdata
;
1464 /* Anyone can call this method */
1466 r
= mac_selinux_access_check(message
, "status", error
);
1470 r
= sd_bus_message_new_method_return(message
, &reply
);
1474 h
= hashmap_new(&string_hash_ops
);
1478 r
= unit_file_get_list(m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
, NULL
, h
);
1482 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
1486 HASHMAP_FOREACH(item
, h
, i
) {
1488 r
= sd_bus_message_append(reply
, "(ss)", item
->path
, unit_file_state_to_string(item
->state
));
1493 unit_file_list_free(h
);
1495 r
= sd_bus_message_close_container(reply
);
1499 return sd_bus_send(NULL
, reply
, NULL
);
1502 unit_file_list_free(h
);
1506 static int method_get_unit_file_state(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1507 Manager
*m
= userdata
;
1509 UnitFileState state
;
1510 UnitFileScope scope
;
1516 /* Anyone can call this method */
1518 r
= mac_selinux_access_check(message
, "status", error
);
1522 r
= sd_bus_message_read(message
, "s", &name
);
1526 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1528 state
= unit_file_get_state(scope
, NULL
, name
);
1532 return sd_bus_reply_method_return(message
, "s", unit_file_state_to_string(state
));
1535 static int method_get_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1536 _cleanup_free_
char *default_target
= NULL
;
1537 Manager
*m
= userdata
;
1538 UnitFileScope scope
;
1544 /* Anyone can call this method */
1546 r
= mac_selinux_access_check(message
, "status", error
);
1550 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1552 r
= unit_file_get_default(scope
, NULL
, &default_target
);
1556 return sd_bus_reply_method_return(message
, "s", default_target
);
1559 static int send_unit_files_changed(sd_bus
*bus
, void *userdata
) {
1560 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
1565 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1569 return sd_bus_send(bus
, message
, NULL
);
1572 static int reply_unit_file_changes_and_free(
1574 sd_bus_message
*message
,
1575 int carries_install_info
,
1576 UnitFileChange
*changes
,
1577 unsigned n_changes
) {
1579 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1583 if (n_changes
> 0) {
1584 r
= bus_foreach_bus(m
, NULL
, send_unit_files_changed
, NULL
);
1586 log_debug_errno(r
, "Failed to send UnitFilesChanged signal: %m");
1589 r
= sd_bus_message_new_method_return(message
, &reply
);
1593 if (carries_install_info
>= 0) {
1594 r
= sd_bus_message_append(reply
, "b", carries_install_info
);
1599 r
= sd_bus_message_open_container(reply
, 'a', "(sss)");
1603 for (i
= 0; i
< n_changes
; i
++) {
1604 r
= sd_bus_message_append(
1606 unit_file_change_type_to_string(changes
[i
].type
),
1613 r
= sd_bus_message_close_container(reply
);
1617 return sd_bus_send(NULL
, reply
, NULL
);
1620 unit_file_changes_free(changes
, n_changes
);
1624 static int method_enable_unit_files_generic(
1625 sd_bus_message
*message
,
1628 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], bool force
, UnitFileChange
**changes
, unsigned *n_changes
),
1629 bool carries_install_info
,
1630 sd_bus_error
*error
) {
1632 _cleanup_strv_free_
char **l
= NULL
;
1633 UnitFileChange
*changes
= NULL
;
1634 unsigned n_changes
= 0;
1635 UnitFileScope scope
;
1636 int runtime
, force
, r
;
1641 r
= sd_bus_message_read_strv(message
, &l
);
1645 r
= sd_bus_message_read(message
, "bb", &runtime
, &force
);
1649 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1653 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1655 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1657 r
= call(scope
, runtime
, NULL
, l
, force
, &changes
, &n_changes
);
1661 return reply_unit_file_changes_and_free(m
, message
, carries_install_info
? r
: -1, changes
, n_changes
);
1664 static int method_enable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1665 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_enable
, true, error
);
1668 static int method_reenable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1669 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_reenable
, true, error
);
1672 static int method_link_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1673 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_link
, false, error
);
1676 static int unit_file_preset_without_mode(UnitFileScope scope
, bool runtime
, const char *root_dir
, char **files
, bool force
, UnitFileChange
**changes
, unsigned *n_changes
) {
1677 return unit_file_preset(scope
, runtime
, root_dir
, files
, UNIT_FILE_PRESET_FULL
, force
, changes
, n_changes
);
1680 static int method_preset_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1681 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_preset_without_mode
, true, error
);
1684 static int method_mask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1685 return method_enable_unit_files_generic(message
, userdata
, "disable", unit_file_mask
, false, error
);
1688 static int method_preset_unit_files_with_mode(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1690 _cleanup_strv_free_
char **l
= NULL
;
1691 UnitFileChange
*changes
= NULL
;
1692 unsigned n_changes
= 0;
1693 Manager
*m
= userdata
;
1694 UnitFilePresetMode mm
;
1695 UnitFileScope scope
;
1696 int runtime
, force
, r
;
1702 r
= sd_bus_message_read_strv(message
, &l
);
1706 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1711 mm
= UNIT_FILE_PRESET_FULL
;
1713 mm
= unit_file_preset_mode_from_string(mode
);
1718 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1722 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1724 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1726 r
= unit_file_preset(scope
, runtime
, NULL
, l
, mm
, force
, &changes
, &n_changes
);
1730 return reply_unit_file_changes_and_free(m
, message
, r
, changes
, n_changes
);
1733 static int method_disable_unit_files_generic(
1734 sd_bus_message
*message
,
1737 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], UnitFileChange
**changes
, unsigned *n_changes
),
1738 sd_bus_error
*error
) {
1740 _cleanup_strv_free_
char **l
= NULL
;
1741 UnitFileChange
*changes
= NULL
;
1742 unsigned n_changes
= 0;
1743 UnitFileScope scope
;
1749 r
= sd_bus_message_read_strv(message
, &l
);
1753 r
= sd_bus_message_read(message
, "b", &runtime
);
1757 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1759 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1763 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1765 r
= call(scope
, runtime
, NULL
, l
, &changes
, &n_changes
);
1769 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1772 static int method_disable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1773 return method_disable_unit_files_generic(message
, userdata
, "disable", unit_file_disable
, error
);
1776 static int method_unmask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1777 return method_disable_unit_files_generic(message
, userdata
, "enable", unit_file_unmask
, error
);
1780 static int method_set_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1781 UnitFileChange
*changes
= NULL
;
1782 unsigned n_changes
= 0;
1783 Manager
*m
= userdata
;
1784 UnitFileScope scope
;
1791 r
= mac_selinux_access_check(message
, "enable", error
);
1795 r
= sd_bus_message_read(message
, "sb", &name
, &force
);
1799 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1803 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1805 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1807 r
= unit_file_set_default(scope
, NULL
, name
, force
, &changes
, &n_changes
);
1811 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1814 static int method_preset_all_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1815 UnitFileChange
*changes
= NULL
;
1816 unsigned n_changes
= 0;
1817 Manager
*m
= userdata
;
1818 UnitFilePresetMode mm
;
1819 UnitFileScope scope
;
1821 int force
, runtime
, r
;
1826 r
= mac_selinux_access_check(message
, "enable", error
);
1830 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1835 mm
= UNIT_FILE_PRESET_FULL
;
1837 mm
= unit_file_preset_mode_from_string(mode
);
1842 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1846 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1848 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1850 r
= unit_file_preset_all(scope
, runtime
, NULL
, mm
, force
, &changes
, &n_changes
);
1854 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1857 static int method_add_dependency_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1858 _cleanup_strv_free_
char **l
= NULL
;
1859 Manager
*m
= userdata
;
1860 UnitFileChange
*changes
= NULL
;
1861 unsigned n_changes
= 0;
1862 UnitFileScope scope
;
1863 int runtime
, force
, r
;
1871 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1875 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1877 r
= sd_bus_message_read_strv(message
, &l
);
1881 r
= sd_bus_message_read(message
, "ssbb", &target
, &type
, &runtime
, &force
);
1885 dep
= unit_dependency_from_string(type
);
1889 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1891 r
= unit_file_add_dependency(scope
, runtime
, NULL
, l
, target
, dep
, force
, &changes
, &n_changes
);
1895 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1898 const sd_bus_vtable bus_manager_vtable
[] = {
1899 SD_BUS_VTABLE_START(0),
1901 SD_BUS_PROPERTY("Version", "s", property_get_version
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1902 SD_BUS_PROPERTY("Features", "s", property_get_features
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1903 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1904 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1905 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1906 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager
, firmware_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1907 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager
, loader_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1908 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager
, kernel_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1909 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager
, initrd_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1910 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager
, userspace_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1911 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager
, finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1912 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager
, security_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1913 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager
, security_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1914 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager
, generators_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1915 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager
, generators_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1916 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager
, units_load_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1917 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager
, units_load_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1918 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level
, property_set_log_level
, 0, 0),
1919 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target
, property_set_log_target
, 0, 0),
1920 SD_BUS_PROPERTY("NNames", "u", property_get_n_names
, 0, 0),
1921 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1922 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs
, 0, 0),
1923 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_installed_jobs
), 0),
1924 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_failed_jobs
), 0),
1925 SD_BUS_PROPERTY("Progress", "d", property_get_progress
, 0, 0),
1926 SD_BUS_PROPERTY("Environment", "as", NULL
, offsetof(Manager
, environment
), 0),
1927 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool
, offsetof(Manager
, confirm_spawn
), SD_BUS_VTABLE_PROPERTY_CONST
),
1928 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool
, offsetof(Manager
, show_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
1929 SD_BUS_PROPERTY("UnitPath", "as", NULL
, offsetof(Manager
, lookup_paths
.unit_path
), SD_BUS_VTABLE_PROPERTY_CONST
),
1930 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1931 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1932 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec
, property_set_runtime_watchdog
, offsetof(Manager
, runtime_watchdog
), 0),
1933 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec
, bus_property_set_usec
, offsetof(Manager
, shutdown_watchdog
), 0),
1934 SD_BUS_PROPERTY("ControlGroup", "s", NULL
, offsetof(Manager
, cgroup_root
), 0),
1935 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state
, 0, 0),
1937 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1938 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid
, SD_BUS_VTABLE_UNPRIVILEGED
),
1939 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1940 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1941 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace
, SD_BUS_VTABLE_UNPRIVILEGED
),
1942 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1943 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1944 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1945 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1946 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1947 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1948 SD_BUS_METHOD("KillUnit", "ssi", NULL
, method_kill_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1949 SD_BUS_METHOD("ResetFailedUnit", "s", NULL
, method_reset_failed_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1950 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL
, method_set_unit_properties
, SD_BUS_VTABLE_UNPRIVILEGED
),
1951 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1952 SD_BUS_METHOD("GetJob", "u", "o", method_get_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
1953 SD_BUS_METHOD("CancelJob", "u", NULL
, method_cancel_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
1954 SD_BUS_METHOD("ClearJobs", NULL
, NULL
, method_clear_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
1955 SD_BUS_METHOD("ResetFailed", NULL
, NULL
, method_reset_failed
, SD_BUS_VTABLE_UNPRIVILEGED
),
1956 SD_BUS_METHOD("ListUnits", NULL
, "a(ssssssouso)", method_list_units
, SD_BUS_VTABLE_UNPRIVILEGED
),
1957 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered
, SD_BUS_VTABLE_UNPRIVILEGED
),
1958 SD_BUS_METHOD("ListJobs", NULL
, "a(usssoo)", method_list_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
1959 SD_BUS_METHOD("Subscribe", NULL
, NULL
, method_subscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
1960 SD_BUS_METHOD("Unsubscribe", NULL
, NULL
, method_unsubscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
1961 SD_BUS_METHOD("Dump", NULL
, "s", method_dump
, SD_BUS_VTABLE_UNPRIVILEGED
),
1962 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
1963 SD_BUS_METHOD("RemoveSnapshot", "s", NULL
, method_remove_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
1964 SD_BUS_METHOD("Reload", NULL
, NULL
, method_reload
, SD_BUS_VTABLE_UNPRIVILEGED
),
1965 SD_BUS_METHOD("Reexecute", NULL
, NULL
, method_reexecute
, SD_BUS_VTABLE_UNPRIVILEGED
),
1966 SD_BUS_METHOD("Exit", NULL
, NULL
, method_exit
, 0),
1967 SD_BUS_METHOD("Reboot", NULL
, NULL
, method_reboot
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1968 SD_BUS_METHOD("PowerOff", NULL
, NULL
, method_poweroff
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1969 SD_BUS_METHOD("Halt", NULL
, NULL
, method_halt
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1970 SD_BUS_METHOD("KExec", NULL
, NULL
, method_kexec
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1971 SD_BUS_METHOD("SwitchRoot", "ss", NULL
, method_switch_root
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1972 SD_BUS_METHOD("SetEnvironment", "as", NULL
, method_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1973 SD_BUS_METHOD("UnsetEnvironment", "as", NULL
, method_unset_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1974 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL
, method_unset_and_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
1975 SD_BUS_METHOD("ListUnitFiles", NULL
, "a(ss)", method_list_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1976 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state
, SD_BUS_VTABLE_UNPRIVILEGED
),
1977 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1978 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1979 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1980 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1981 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1982 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode
, SD_BUS_VTABLE_UNPRIVILEGED
),
1983 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1984 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1985 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
1986 SD_BUS_METHOD("GetDefaultTarget", NULL
, "s", method_get_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
1987 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1988 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
1990 SD_BUS_SIGNAL("UnitNew", "so", 0),
1991 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1992 SD_BUS_SIGNAL("JobNew", "uos", 0),
1993 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1994 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1995 SD_BUS_SIGNAL("UnitFilesChanged", NULL
, 0),
1996 SD_BUS_SIGNAL("Reloading", "b", 0),
2001 static int send_finished(sd_bus
*bus
, void *userdata
) {
2002 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2003 usec_t
*times
= userdata
;
2009 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2013 r
= sd_bus_message_append(message
, "tttttt", times
[0], times
[1], times
[2], times
[3], times
[4], times
[5]);
2017 return sd_bus_send(bus
, message
, NULL
);
2020 void bus_manager_send_finished(
2022 usec_t firmware_usec
,
2026 usec_t userspace_usec
,
2027 usec_t total_usec
) {
2033 r
= bus_foreach_bus(
2046 log_debug_errno(r
, "Failed to send finished signal: %m");
2049 static int send_reloading(sd_bus
*bus
, void *userdata
) {
2050 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2055 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2059 r
= sd_bus_message_append(message
, "b", PTR_TO_INT(userdata
));
2063 return sd_bus_send(bus
, message
, NULL
);
2066 void bus_manager_send_reloading(Manager
*m
, bool active
) {
2071 r
= bus_foreach_bus(m
, NULL
, send_reloading
, INT_TO_PTR(active
));
2073 log_debug_errno(r
, "Failed to send reloading signal: %m");
2076 static int send_changed_signal(sd_bus
*bus
, void *userdata
) {
2079 return sd_bus_emit_properties_changed_strv(bus
,
2080 "/org/freedesktop/systemd1",
2081 "org.freedesktop.systemd1.Manager",
2085 void bus_manager_send_change_signal(Manager
*m
) {
2090 r
= bus_foreach_bus(m
, NULL
, send_changed_signal
, NULL
);
2092 log_debug_errno(r
, "Failed to send manager change signal: %m");