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 /* Exit() (in contrast to SetExitCode()) is actually allowed even if
1205 * we are running on the host. It will fall back on reboot() in
1206 * systemd-shutdown if it cannot do the exit() because it isn't a
1209 m
->exit_code
= MANAGER_EXIT
;
1211 return sd_bus_reply_method_return(message
, NULL
);
1214 static int method_reboot(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1215 Manager
*m
= userdata
;
1221 r
= mac_selinux_access_check(message
, "reboot", error
);
1225 if (m
->running_as
!= MANAGER_SYSTEM
)
1226 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Reboot is only supported for system managers.");
1228 m
->exit_code
= MANAGER_REBOOT
;
1230 return sd_bus_reply_method_return(message
, NULL
);
1233 static int method_poweroff(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1234 Manager
*m
= userdata
;
1240 r
= mac_selinux_access_check(message
, "halt", error
);
1244 if (m
->running_as
!= MANAGER_SYSTEM
)
1245 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Powering off is only supported for system managers.");
1247 m
->exit_code
= MANAGER_POWEROFF
;
1249 return sd_bus_reply_method_return(message
, NULL
);
1252 static int method_halt(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1253 Manager
*m
= userdata
;
1259 r
= mac_selinux_access_check(message
, "halt", error
);
1263 if (m
->running_as
!= MANAGER_SYSTEM
)
1264 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Halt is only supported for system managers.");
1266 m
->exit_code
= MANAGER_HALT
;
1268 return sd_bus_reply_method_return(message
, NULL
);
1271 static int method_kexec(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1272 Manager
*m
= userdata
;
1278 r
= mac_selinux_access_check(message
, "reboot", error
);
1282 if (m
->running_as
!= MANAGER_SYSTEM
)
1283 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "KExec is only supported for system managers.");
1285 m
->exit_code
= MANAGER_KEXEC
;
1287 return sd_bus_reply_method_return(message
, NULL
);
1290 static int method_switch_root(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1291 char *ri
= NULL
, *rt
= NULL
;
1292 const char *root
, *init
;
1293 Manager
*m
= userdata
;
1299 r
= mac_selinux_access_check(message
, "reboot", error
);
1303 if (m
->running_as
!= MANAGER_SYSTEM
)
1304 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "Root switching is only supported by system manager.");
1306 r
= sd_bus_message_read(message
, "ss", &root
, &init
);
1310 if (path_equal(root
, "/") || !path_is_absolute(root
))
1311 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid switch root path %s", root
);
1314 if (isempty(init
)) {
1315 if (!path_is_os_tree(root
))
1316 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
);
1318 _cleanup_free_
char *p
= NULL
;
1320 if (!path_is_absolute(init
))
1321 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid init path %s", init
);
1323 p
= strappend(root
, init
);
1327 if (access(p
, X_OK
) < 0)
1328 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Specified init binary %s does not exist.", p
);
1335 if (!isempty(init
)) {
1343 free(m
->switch_root
);
1344 m
->switch_root
= rt
;
1346 free(m
->switch_root_init
);
1347 m
->switch_root_init
= ri
;
1349 m
->exit_code
= MANAGER_SWITCH_ROOT
;
1351 return sd_bus_reply_method_return(message
, NULL
);
1354 static int method_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1355 _cleanup_strv_free_
char **plus
= NULL
;
1356 Manager
*m
= userdata
;
1362 r
= mac_selinux_access_check(message
, "reload", error
);
1366 r
= sd_bus_message_read_strv(message
, &plus
);
1369 if (!strv_env_is_valid(plus
))
1370 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1372 r
= bus_verify_set_environment_async(m
, message
, error
);
1376 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1378 r
= manager_environment_add(m
, NULL
, plus
);
1382 return sd_bus_reply_method_return(message
, NULL
);
1385 static int method_unset_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1386 _cleanup_strv_free_
char **minus
= NULL
;
1387 Manager
*m
= userdata
;
1393 r
= mac_selinux_access_check(message
, "reload", error
);
1397 r
= sd_bus_message_read_strv(message
, &minus
);
1401 if (!strv_env_name_or_assignment_is_valid(minus
))
1402 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1404 r
= bus_verify_set_environment_async(m
, message
, error
);
1408 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1410 r
= manager_environment_add(m
, minus
, NULL
);
1414 return sd_bus_reply_method_return(message
, NULL
);
1417 static int method_unset_and_set_environment(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1418 _cleanup_strv_free_
char **minus
= NULL
, **plus
= NULL
;
1419 Manager
*m
= userdata
;
1425 r
= mac_selinux_access_check(message
, "reload", error
);
1429 r
= sd_bus_message_read_strv(message
, &minus
);
1433 r
= sd_bus_message_read_strv(message
, &plus
);
1437 if (!strv_env_name_or_assignment_is_valid(minus
))
1438 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment variable names or assignments");
1439 if (!strv_env_is_valid(plus
))
1440 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Invalid environment assignments");
1442 r
= bus_verify_set_environment_async(m
, message
, error
);
1446 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1448 r
= manager_environment_add(m
, minus
, plus
);
1452 return sd_bus_reply_method_return(message
, NULL
);
1455 static int method_set_exit_code(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1457 Manager
*m
= userdata
;
1463 r
= mac_selinux_access_check(message
, "exit", error
);
1467 r
= sd_bus_message_read_basic(message
, 'y', &code
);
1471 if (m
->running_as
== MANAGER_SYSTEM
&& detect_container() <= 0)
1472 return sd_bus_error_setf(error
, SD_BUS_ERROR_NOT_SUPPORTED
, "ExitCode can only be set for user service managers or in containers.");
1474 m
->return_value
= code
;
1476 return sd_bus_reply_method_return(message
, NULL
);
1479 static int method_list_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1480 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1481 Manager
*m
= userdata
;
1490 /* Anyone can call this method */
1492 r
= mac_selinux_access_check(message
, "status", error
);
1496 r
= sd_bus_message_new_method_return(message
, &reply
);
1500 h
= hashmap_new(&string_hash_ops
);
1504 r
= unit_file_get_list(m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
, NULL
, h
);
1508 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
1512 HASHMAP_FOREACH(item
, h
, i
) {
1514 r
= sd_bus_message_append(reply
, "(ss)", item
->path
, unit_file_state_to_string(item
->state
));
1519 unit_file_list_free(h
);
1521 r
= sd_bus_message_close_container(reply
);
1525 return sd_bus_send(NULL
, reply
, NULL
);
1528 unit_file_list_free(h
);
1532 static int method_get_unit_file_state(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1533 Manager
*m
= userdata
;
1535 UnitFileState state
;
1536 UnitFileScope scope
;
1542 /* Anyone can call this method */
1544 r
= mac_selinux_access_check(message
, "status", error
);
1548 r
= sd_bus_message_read(message
, "s", &name
);
1552 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1554 state
= unit_file_get_state(scope
, NULL
, name
);
1558 return sd_bus_reply_method_return(message
, "s", unit_file_state_to_string(state
));
1561 static int method_get_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1562 _cleanup_free_
char *default_target
= NULL
;
1563 Manager
*m
= userdata
;
1564 UnitFileScope scope
;
1570 /* Anyone can call this method */
1572 r
= mac_selinux_access_check(message
, "status", error
);
1576 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1578 r
= unit_file_get_default(scope
, NULL
, &default_target
);
1582 return sd_bus_reply_method_return(message
, "s", default_target
);
1585 static int send_unit_files_changed(sd_bus
*bus
, void *userdata
) {
1586 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
1591 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1595 return sd_bus_send(bus
, message
, NULL
);
1598 static int reply_unit_file_changes_and_free(
1600 sd_bus_message
*message
,
1601 int carries_install_info
,
1602 UnitFileChange
*changes
,
1603 unsigned n_changes
) {
1605 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1609 if (n_changes
> 0) {
1610 r
= bus_foreach_bus(m
, NULL
, send_unit_files_changed
, NULL
);
1612 log_debug_errno(r
, "Failed to send UnitFilesChanged signal: %m");
1615 r
= sd_bus_message_new_method_return(message
, &reply
);
1619 if (carries_install_info
>= 0) {
1620 r
= sd_bus_message_append(reply
, "b", carries_install_info
);
1625 r
= sd_bus_message_open_container(reply
, 'a', "(sss)");
1629 for (i
= 0; i
< n_changes
; i
++) {
1630 r
= sd_bus_message_append(
1632 unit_file_change_type_to_string(changes
[i
].type
),
1639 r
= sd_bus_message_close_container(reply
);
1643 return sd_bus_send(NULL
, reply
, NULL
);
1646 unit_file_changes_free(changes
, n_changes
);
1650 static int method_enable_unit_files_generic(
1651 sd_bus_message
*message
,
1654 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], bool force
, UnitFileChange
**changes
, unsigned *n_changes
),
1655 bool carries_install_info
,
1656 sd_bus_error
*error
) {
1658 _cleanup_strv_free_
char **l
= NULL
;
1659 UnitFileChange
*changes
= NULL
;
1660 unsigned n_changes
= 0;
1661 UnitFileScope scope
;
1662 int runtime
, force
, r
;
1667 r
= sd_bus_message_read_strv(message
, &l
);
1671 r
= sd_bus_message_read(message
, "bb", &runtime
, &force
);
1675 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1679 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1681 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1683 r
= call(scope
, runtime
, NULL
, l
, force
, &changes
, &n_changes
);
1687 return reply_unit_file_changes_and_free(m
, message
, carries_install_info
? r
: -1, changes
, n_changes
);
1690 static int method_enable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1691 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_enable
, true, error
);
1694 static int method_reenable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1695 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_reenable
, true, error
);
1698 static int method_link_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1699 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_link
, false, error
);
1702 static int unit_file_preset_without_mode(UnitFileScope scope
, bool runtime
, const char *root_dir
, char **files
, bool force
, UnitFileChange
**changes
, unsigned *n_changes
) {
1703 return unit_file_preset(scope
, runtime
, root_dir
, files
, UNIT_FILE_PRESET_FULL
, force
, changes
, n_changes
);
1706 static int method_preset_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1707 return method_enable_unit_files_generic(message
, userdata
, "enable", unit_file_preset_without_mode
, true, error
);
1710 static int method_mask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1711 return method_enable_unit_files_generic(message
, userdata
, "disable", unit_file_mask
, false, error
);
1714 static int method_preset_unit_files_with_mode(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1716 _cleanup_strv_free_
char **l
= NULL
;
1717 UnitFileChange
*changes
= NULL
;
1718 unsigned n_changes
= 0;
1719 Manager
*m
= userdata
;
1720 UnitFilePresetMode mm
;
1721 UnitFileScope scope
;
1722 int runtime
, force
, r
;
1728 r
= sd_bus_message_read_strv(message
, &l
);
1732 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1737 mm
= UNIT_FILE_PRESET_FULL
;
1739 mm
= unit_file_preset_mode_from_string(mode
);
1744 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1748 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1750 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1752 r
= unit_file_preset(scope
, runtime
, NULL
, l
, mm
, force
, &changes
, &n_changes
);
1756 return reply_unit_file_changes_and_free(m
, message
, r
, changes
, n_changes
);
1759 static int method_disable_unit_files_generic(
1760 sd_bus_message
*message
,
1763 int (*call
)(UnitFileScope scope
, bool runtime
, const char *root_dir
, char *files
[], UnitFileChange
**changes
, unsigned *n_changes
),
1764 sd_bus_error
*error
) {
1766 _cleanup_strv_free_
char **l
= NULL
;
1767 UnitFileChange
*changes
= NULL
;
1768 unsigned n_changes
= 0;
1769 UnitFileScope scope
;
1775 r
= sd_bus_message_read_strv(message
, &l
);
1779 r
= sd_bus_message_read(message
, "b", &runtime
);
1783 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1785 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1789 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1791 r
= call(scope
, runtime
, NULL
, l
, &changes
, &n_changes
);
1795 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1798 static int method_disable_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1799 return method_disable_unit_files_generic(message
, userdata
, "disable", unit_file_disable
, error
);
1802 static int method_unmask_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1803 return method_disable_unit_files_generic(message
, userdata
, "enable", unit_file_unmask
, error
);
1806 static int method_set_default_target(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1807 UnitFileChange
*changes
= NULL
;
1808 unsigned n_changes
= 0;
1809 Manager
*m
= userdata
;
1810 UnitFileScope scope
;
1817 r
= mac_selinux_access_check(message
, "enable", error
);
1821 r
= sd_bus_message_read(message
, "sb", &name
, &force
);
1825 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1829 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1831 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1833 r
= unit_file_set_default(scope
, NULL
, name
, force
, &changes
, &n_changes
);
1837 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1840 static int method_preset_all_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1841 UnitFileChange
*changes
= NULL
;
1842 unsigned n_changes
= 0;
1843 Manager
*m
= userdata
;
1844 UnitFilePresetMode mm
;
1845 UnitFileScope scope
;
1847 int force
, runtime
, r
;
1852 r
= mac_selinux_access_check(message
, "enable", error
);
1856 r
= sd_bus_message_read(message
, "sbb", &mode
, &runtime
, &force
);
1861 mm
= UNIT_FILE_PRESET_FULL
;
1863 mm
= unit_file_preset_mode_from_string(mode
);
1868 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1872 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1874 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1876 r
= unit_file_preset_all(scope
, runtime
, NULL
, mm
, force
, &changes
, &n_changes
);
1880 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1883 static int method_add_dependency_unit_files(sd_bus_message
*message
, void *userdata
, sd_bus_error
*error
) {
1884 _cleanup_strv_free_
char **l
= NULL
;
1885 Manager
*m
= userdata
;
1886 UnitFileChange
*changes
= NULL
;
1887 unsigned n_changes
= 0;
1888 UnitFileScope scope
;
1889 int runtime
, force
, r
;
1897 r
= bus_verify_manage_unit_files_async(m
, message
, error
);
1901 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1903 r
= sd_bus_message_read_strv(message
, &l
);
1907 r
= sd_bus_message_read(message
, "ssbb", &target
, &type
, &runtime
, &force
);
1911 dep
= unit_dependency_from_string(type
);
1915 scope
= m
->running_as
== MANAGER_SYSTEM
? UNIT_FILE_SYSTEM
: UNIT_FILE_USER
;
1917 r
= unit_file_add_dependency(scope
, runtime
, NULL
, l
, target
, dep
, force
, &changes
, &n_changes
);
1921 return reply_unit_file_changes_and_free(m
, message
, -1, changes
, n_changes
);
1924 const sd_bus_vtable bus_manager_vtable
[] = {
1925 SD_BUS_VTABLE_START(0),
1927 SD_BUS_PROPERTY("Version", "s", property_get_version
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1928 SD_BUS_PROPERTY("Features", "s", property_get_features
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1929 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1930 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1931 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted
, 0, SD_BUS_VTABLE_PROPERTY_CONST
),
1932 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager
, firmware_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1933 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager
, loader_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1934 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager
, kernel_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1935 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager
, initrd_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1936 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager
, userspace_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1937 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager
, finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1938 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager
, security_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1939 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager
, security_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1940 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager
, generators_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1941 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager
, generators_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1942 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager
, units_load_start_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1943 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager
, units_load_finish_timestamp
), SD_BUS_VTABLE_PROPERTY_CONST
),
1944 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level
, property_set_log_level
, 0, 0),
1945 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target
, property_set_log_target
, 0, 0),
1946 SD_BUS_PROPERTY("NNames", "u", property_get_n_names
, 0, 0),
1947 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units
, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE
),
1948 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs
, 0, 0),
1949 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_installed_jobs
), 0),
1950 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned
, offsetof(Manager
, n_failed_jobs
), 0),
1951 SD_BUS_PROPERTY("Progress", "d", property_get_progress
, 0, 0),
1952 SD_BUS_PROPERTY("Environment", "as", NULL
, offsetof(Manager
, environment
), 0),
1953 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool
, offsetof(Manager
, confirm_spawn
), SD_BUS_VTABLE_PROPERTY_CONST
),
1954 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool
, offsetof(Manager
, show_status
), SD_BUS_VTABLE_PROPERTY_CONST
),
1955 SD_BUS_PROPERTY("UnitPath", "as", NULL
, offsetof(Manager
, lookup_paths
.unit_path
), SD_BUS_VTABLE_PROPERTY_CONST
),
1956 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1957 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output
, offsetof(Manager
, default_std_output
), SD_BUS_VTABLE_PROPERTY_CONST
),
1958 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec
, property_set_runtime_watchdog
, offsetof(Manager
, runtime_watchdog
), 0),
1959 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec
, bus_property_set_usec
, offsetof(Manager
, shutdown_watchdog
), 0),
1960 SD_BUS_PROPERTY("ControlGroup", "s", NULL
, offsetof(Manager
, cgroup_root
), 0),
1961 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state
, 0, 0),
1962 SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned
, offsetof(Manager
, return_value
), 0),
1964 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1965 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid
, SD_BUS_VTABLE_UNPRIVILEGED
),
1966 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1967 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1968 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace
, SD_BUS_VTABLE_UNPRIVILEGED
),
1969 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1970 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1971 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1972 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1973 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1974 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1975 SD_BUS_METHOD("KillUnit", "ssi", NULL
, method_kill_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1976 SD_BUS_METHOD("ResetFailedUnit", "s", NULL
, method_reset_failed_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1977 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL
, method_set_unit_properties
, SD_BUS_VTABLE_UNPRIVILEGED
),
1978 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit
, SD_BUS_VTABLE_UNPRIVILEGED
),
1979 SD_BUS_METHOD("GetJob", "u", "o", method_get_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
1980 SD_BUS_METHOD("CancelJob", "u", NULL
, method_cancel_job
, SD_BUS_VTABLE_UNPRIVILEGED
),
1981 SD_BUS_METHOD("ClearJobs", NULL
, NULL
, method_clear_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
1982 SD_BUS_METHOD("ResetFailed", NULL
, NULL
, method_reset_failed
, SD_BUS_VTABLE_UNPRIVILEGED
),
1983 SD_BUS_METHOD("ListUnits", NULL
, "a(ssssssouso)", method_list_units
, SD_BUS_VTABLE_UNPRIVILEGED
),
1984 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered
, SD_BUS_VTABLE_UNPRIVILEGED
),
1985 SD_BUS_METHOD("ListJobs", NULL
, "a(usssoo)", method_list_jobs
, SD_BUS_VTABLE_UNPRIVILEGED
),
1986 SD_BUS_METHOD("Subscribe", NULL
, NULL
, method_subscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
1987 SD_BUS_METHOD("Unsubscribe", NULL
, NULL
, method_unsubscribe
, SD_BUS_VTABLE_UNPRIVILEGED
),
1988 SD_BUS_METHOD("Dump", NULL
, "s", method_dump
, SD_BUS_VTABLE_UNPRIVILEGED
),
1989 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
1990 SD_BUS_METHOD("RemoveSnapshot", "s", NULL
, method_remove_snapshot
, SD_BUS_VTABLE_UNPRIVILEGED
),
1991 SD_BUS_METHOD("Reload", NULL
, NULL
, method_reload
, SD_BUS_VTABLE_UNPRIVILEGED
),
1992 SD_BUS_METHOD("Reexecute", NULL
, NULL
, method_reexecute
, SD_BUS_VTABLE_UNPRIVILEGED
),
1993 SD_BUS_METHOD("Exit", NULL
, NULL
, method_exit
, 0),
1994 SD_BUS_METHOD("Reboot", NULL
, NULL
, method_reboot
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1995 SD_BUS_METHOD("PowerOff", NULL
, NULL
, method_poweroff
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1996 SD_BUS_METHOD("Halt", NULL
, NULL
, method_halt
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1997 SD_BUS_METHOD("KExec", NULL
, NULL
, method_kexec
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1998 SD_BUS_METHOD("SwitchRoot", "ss", NULL
, method_switch_root
, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT
)),
1999 SD_BUS_METHOD("SetEnvironment", "as", NULL
, method_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
2000 SD_BUS_METHOD("UnsetEnvironment", "as", NULL
, method_unset_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
2001 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL
, method_unset_and_set_environment
, SD_BUS_VTABLE_UNPRIVILEGED
),
2002 SD_BUS_METHOD("ListUnitFiles", NULL
, "a(ss)", method_list_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2003 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state
, SD_BUS_VTABLE_UNPRIVILEGED
),
2004 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2005 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2006 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2007 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2008 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2009 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode
, SD_BUS_VTABLE_UNPRIVILEGED
),
2010 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2011 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2012 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
2013 SD_BUS_METHOD("GetDefaultTarget", NULL
, "s", method_get_default_target
, SD_BUS_VTABLE_UNPRIVILEGED
),
2014 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2015 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files
, SD_BUS_VTABLE_UNPRIVILEGED
),
2016 SD_BUS_METHOD("SetExitCode", "y", NULL
, method_set_exit_code
, SD_BUS_VTABLE_UNPRIVILEGED
),
2018 SD_BUS_SIGNAL("UnitNew", "so", 0),
2019 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2020 SD_BUS_SIGNAL("JobNew", "uos", 0),
2021 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2022 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2023 SD_BUS_SIGNAL("UnitFilesChanged", NULL
, 0),
2024 SD_BUS_SIGNAL("Reloading", "b", 0),
2029 static int send_finished(sd_bus
*bus
, void *userdata
) {
2030 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2031 usec_t
*times
= userdata
;
2037 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2041 r
= sd_bus_message_append(message
, "tttttt", times
[0], times
[1], times
[2], times
[3], times
[4], times
[5]);
2045 return sd_bus_send(bus
, message
, NULL
);
2048 void bus_manager_send_finished(
2050 usec_t firmware_usec
,
2054 usec_t userspace_usec
,
2055 usec_t total_usec
) {
2061 r
= bus_foreach_bus(
2074 log_debug_errno(r
, "Failed to send finished signal: %m");
2077 static int send_reloading(sd_bus
*bus
, void *userdata
) {
2078 _cleanup_bus_message_unref_ sd_bus_message
*message
= NULL
;
2083 r
= sd_bus_message_new_signal(bus
, &message
, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2087 r
= sd_bus_message_append(message
, "b", PTR_TO_INT(userdata
));
2091 return sd_bus_send(bus
, message
, NULL
);
2094 void bus_manager_send_reloading(Manager
*m
, bool active
) {
2099 r
= bus_foreach_bus(m
, NULL
, send_reloading
, INT_TO_PTR(active
));
2101 log_debug_errno(r
, "Failed to send reloading signal: %m");
2104 static int send_changed_signal(sd_bus
*bus
, void *userdata
) {
2107 return sd_bus_emit_properties_changed_strv(bus
,
2108 "/org/freedesktop/systemd1",
2109 "org.freedesktop.systemd1.Manager",
2113 void bus_manager_send_change_signal(Manager
*m
) {
2118 r
= bus_foreach_bus(m
, NULL
, send_changed_signal
, NULL
);
2120 log_debug_errno(r
, "Failed to send manager change signal: %m");