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"
44 static int property_get_version(
47 const char *interface,
49 sd_bus_message *reply,
51 sd_bus_error *error) {
56 return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
59 static int property_get_features(
62 const char *interface,
64 sd_bus_message *reply,
66 sd_bus_error *error) {
71 return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
74 static int property_get_virtualization(
77 const char *interface,
79 sd_bus_message *reply,
81 sd_bus_error *error) {
83 const char *id = NULL;
88 detect_virtualization(&id);
90 return sd_bus_message_append(reply, "s", id);
93 static int property_get_architecture(
96 const char *interface,
98 sd_bus_message *reply,
100 sd_bus_error *error) {
105 return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
108 static int property_get_tainted(
111 const char *interface,
112 const char *property,
113 sd_bus_message *reply,
115 sd_bus_error *error) {
117 char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
118 _cleanup_free_ char *p = NULL;
119 Manager *m = userdata;
126 e = stpcpy(e, "split-usr:");
128 if (readlink_malloc("/etc/mtab", &p) < 0)
129 e = stpcpy(e, "mtab-not-symlink:");
131 if (access("/proc/cgroups", F_OK) < 0)
132 e = stpcpy(e, "cgroups-missing:");
134 if (clock_is_localtime() > 0)
135 e = stpcpy(e, "local-hwclock:");
137 /* remove the last ':' */
141 return sd_bus_message_append(reply, "s", buf);
144 static int property_get_log_target(
147 const char *interface,
148 const char *property,
149 sd_bus_message *reply,
151 sd_bus_error *error) {
156 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
159 static int property_set_log_target(
162 const char *interface,
163 const char *property,
164 sd_bus_message *value,
166 sd_bus_error *error) {
174 r = sd_bus_message_read(value, "s", &t);
178 return log_set_target_from_string(t);
181 static int property_get_log_level(
184 const char *interface,
185 const char *property,
186 sd_bus_message *reply,
188 sd_bus_error *error) {
190 _cleanup_free_ char *t = NULL;
196 r = log_level_to_string_alloc(log_get_max_level(), &t);
200 return sd_bus_message_append(reply, "s", t);
203 static int property_set_log_level(
206 const char *interface,
207 const char *property,
208 sd_bus_message *value,
210 sd_bus_error *error) {
218 r = sd_bus_message_read(value, "s", &t);
222 return log_set_max_level_from_string(t);
225 static int property_get_n_names(
228 const char *interface,
229 const char *property,
230 sd_bus_message *reply,
232 sd_bus_error *error) {
234 Manager *m = userdata;
240 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
243 static int property_get_n_failed_units(
246 const char *interface,
247 const char *property,
248 sd_bus_message *reply,
250 sd_bus_error *error) {
252 Manager *m = userdata;
258 return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
261 static int property_get_n_jobs(
264 const char *interface,
265 const char *property,
266 sd_bus_message *reply,
268 sd_bus_error *error) {
270 Manager *m = userdata;
276 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
279 static int property_get_progress(
282 const char *interface,
283 const char *property,
284 sd_bus_message *reply,
286 sd_bus_error *error) {
288 Manager *m = userdata;
295 if (dual_timestamp_is_set(&m->finish_timestamp))
298 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
300 return sd_bus_message_append(reply, "d", d);
303 static int property_get_system_state(
306 const char *interface,
307 const char *property,
308 sd_bus_message *reply,
310 sd_bus_error *error) {
312 Manager *m = userdata;
318 return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
321 static int property_set_runtime_watchdog(
324 const char *interface,
325 const char *property,
326 sd_bus_message *value,
328 sd_bus_error *error) {
330 usec_t *t = userdata;
336 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
338 r = sd_bus_message_read(value, "t", t);
342 return watchdog_set_timeout(t);
345 static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
346 _cleanup_free_ char *path = NULL;
347 Manager *m = userdata;
356 /* Anyone can call this method */
358 r = sd_bus_message_read(message, "s", &name);
363 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
366 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
370 r = sd_bus_creds_get_pid(creds, &pid);
374 u = manager_get_unit_by_pid(m, pid);
376 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
378 u = manager_get_unit(m, name);
380 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
383 r = mac_selinux_unit_access_check(u, message, "status", error);
387 path = unit_dbus_path(u);
391 return sd_bus_reply_method_return(message, "o", path);
394 static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
395 _cleanup_free_ char *path = NULL;
396 Manager *m = userdata;
405 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
407 /* Anyone can call this method */
409 r = sd_bus_message_read(message, "u", &pid);
413 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
416 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
418 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
422 r = sd_bus_creds_get_pid(creds, &pid);
427 u = manager_get_unit_by_pid(m, pid);
429 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
431 r = mac_selinux_unit_access_check(u, message, "status", error);
435 path = unit_dbus_path(u);
439 return sd_bus_reply_method_return(message, "o", path);
442 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
443 _cleanup_free_ char *path = NULL;
444 Manager *m = userdata;
453 /* Anyone can call this method */
455 r = sd_bus_message_read(message, "s", &name);
460 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
463 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
467 r = sd_bus_creds_get_pid(creds, &pid);
471 u = manager_get_unit_by_pid(m, pid);
473 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
475 r = manager_load_unit(m, name, NULL, error, &u);
480 r = mac_selinux_unit_access_check(u, message, "status", error);
484 path = unit_dbus_path(u);
488 return sd_bus_reply_method_return(message, "o", path);
491 static int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
500 r = sd_bus_message_read(message, "s", &name);
504 r = manager_load_unit(m, name, NULL, error, &u);
508 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
511 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
512 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
515 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
516 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
519 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
520 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
523 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
524 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
527 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
528 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
531 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
532 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
535 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
536 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
539 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
540 Manager *m = userdata;
541 const char *old_name;
549 r = sd_bus_message_read(message, "s", &old_name);
553 u = manager_get_unit(m, old_name);
554 if (!u || !u->job || u->job->type != JOB_START)
555 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
557 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
560 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
561 Manager *m = userdata;
570 r = sd_bus_message_read(message, "s", &name);
574 u = manager_get_unit(m, name);
576 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
578 return bus_unit_method_kill(bus, message, u, error);
581 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
582 Manager *m = userdata;
591 r = sd_bus_message_read(message, "s", &name);
595 u = manager_get_unit(m, name);
597 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
599 return bus_unit_method_reset_failed(bus, message, u, error);
602 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
603 Manager *m = userdata;
612 r = sd_bus_message_read(message, "s", &name);
616 u = manager_get_unit(m, name);
618 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
620 return bus_unit_method_set_properties(bus, message, u, error);
623 static int transient_unit_from_message(
625 sd_bus_message *message,
628 sd_bus_error *error) {
637 r = manager_load_unit(m, name, NULL, error, &u);
641 if (u->load_state != UNIT_NOT_FOUND ||
642 set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
643 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
645 /* OK, the unit failed to load and is unreferenced, now let's
646 * fill in the transient data instead */
647 r = unit_make_transient(u);
651 /* Set our properties */
652 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
661 static int transient_aux_units_from_message(
663 sd_bus_message *message,
664 sd_bus_error *error) {
673 r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
677 while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
681 r = sd_bus_message_read(message, "s", &name);
685 r = transient_unit_from_message(m, message, name, &u, error);
686 if (r < 0 && r != -EEXIST)
695 r = sd_bus_message_exit_container(message);
702 r = sd_bus_message_exit_container(message);
709 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
710 const char *name, *smode;
711 Manager *m = userdata;
721 r = mac_selinux_access_check(message, "start", error);
725 r = sd_bus_message_read(message, "ss", &name, &smode);
729 t = unit_name_to_type(name);
731 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
733 if (!unit_vtable[t]->can_transient)
734 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
736 mode = job_mode_from_string(smode);
738 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
740 r = bus_verify_manage_units_async(m, message, error);
744 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
746 r = transient_unit_from_message(m, message, name, &u, error);
750 r = transient_aux_units_from_message(m, message, error);
754 /* And load this stub fully */
759 manager_dispatch_load_queue(m);
761 /* Finally, start it */
762 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
765 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
766 _cleanup_free_ char *path = NULL;
767 Manager *m = userdata;
776 /* Anyone can call this method */
778 r = sd_bus_message_read(message, "u", &id);
782 j = manager_get_job(m, id);
784 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
786 r = mac_selinux_unit_access_check(j->unit, message, "status", error);
790 path = job_dbus_path(j);
794 return sd_bus_reply_method_return(message, "o", path);
797 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
798 Manager *m = userdata;
807 r = sd_bus_message_read(message, "u", &id);
811 j = manager_get_job(m, id);
813 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
815 return bus_job_method_cancel(bus, message, j, error);
818 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
819 Manager *m = userdata;
826 r = mac_selinux_access_check(message, "reload", error);
830 r = bus_verify_manage_units_async(m, message, error);
834 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
836 manager_clear_jobs(m);
838 return sd_bus_reply_method_return(message, NULL);
841 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
842 Manager *m = userdata;
849 r = mac_selinux_access_check(message, "reload", error);
853 r = bus_verify_manage_units_async(m, message, error);
857 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
859 manager_reset_failed(m);
861 return sd_bus_reply_method_return(message, NULL);
864 static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
865 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
866 Manager *m = userdata;
876 /* Anyone can call this method */
878 r = mac_selinux_access_check(message, "status", error);
882 r = sd_bus_message_new_method_return(message, &reply);
886 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
890 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
891 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
897 following = unit_following(u);
899 if (!strv_isempty(states) &&
900 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
901 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
902 !strv_contains(states, unit_sub_state_to_string(u)))
905 unit_path = unit_dbus_path(u);
910 job_path = job_dbus_path(u->job);
915 r = sd_bus_message_append(
916 reply, "(ssssssouso)",
919 unit_load_state_to_string(u->load_state),
920 unit_active_state_to_string(unit_active_state(u)),
921 unit_sub_state_to_string(u),
922 following ? following->id : "",
924 u->job ? u->job->id : 0,
925 u->job ? job_type_to_string(u->job->type) : "",
926 job_path ? job_path : "/");
931 r = sd_bus_message_close_container(reply);
935 return sd_bus_send(bus, reply, NULL);
938 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
939 return list_units_filtered(bus, message, userdata, error, NULL);
942 static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
943 _cleanup_strv_free_ char **states = NULL;
946 r = sd_bus_message_read_strv(message, &states);
950 return list_units_filtered(bus, message, userdata, error, states);
953 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
954 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
955 Manager *m = userdata;
964 /* Anyone can call this method */
966 r = mac_selinux_access_check(message, "status", error);
970 r = sd_bus_message_new_method_return(message, &reply);
974 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
978 HASHMAP_FOREACH(j, m->jobs, i) {
979 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
981 job_path = job_dbus_path(j);
985 unit_path = unit_dbus_path(j->unit);
989 r = sd_bus_message_append(
993 job_type_to_string(j->type),
994 job_state_to_string(j->state),
1001 r = sd_bus_message_close_container(reply);
1005 return sd_bus_send(bus, reply, NULL);
1008 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1009 Manager *m = userdata;
1016 /* Anyone can call this method */
1018 r = mac_selinux_access_check(message, "status", error);
1022 if (bus == m->api_bus) {
1024 /* Note that direct bus connection subscribe by
1025 * default, we only track peers on the API bus here */
1027 if (!m->subscribed) {
1028 r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
1033 r = sd_bus_track_add_sender(m->subscribed, message);
1037 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1040 return sd_bus_reply_method_return(message, NULL);
1043 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1044 Manager *m = userdata;
1051 /* Anyone can call this method */
1053 r = mac_selinux_access_check(message, "status", error);
1057 if (bus == m->api_bus) {
1058 r = sd_bus_track_remove_sender(m->subscribed, message);
1062 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1065 return sd_bus_reply_method_return(message, NULL);
1068 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1069 _cleanup_free_ char *dump = NULL;
1070 _cleanup_fclose_ FILE *f = NULL;
1071 Manager *m = userdata;
1079 /* Anyone can call this method */
1081 r = mac_selinux_access_check(message, "status", error);
1085 f = open_memstream(&dump, &size);
1089 manager_dump_units(m, f, NULL);
1090 manager_dump_jobs(m, f, NULL);
1097 return sd_bus_reply_method_return(message, "s", dump);
1100 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1101 _cleanup_free_ char *path = NULL;
1102 Manager *m = userdata;
1112 r = mac_selinux_access_check(message, "start", error);
1116 r = sd_bus_message_read(message, "sb", &name, &cleanup);
1123 r = bus_verify_manage_units_async(m, message, error);
1127 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1129 r = snapshot_create(m, name, cleanup, error, &s);
1133 path = unit_dbus_path(UNIT(s));
1137 return sd_bus_reply_method_return(message, "o", path);
1140 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1141 Manager *m = userdata;
1150 r = sd_bus_message_read(message, "s", &name);
1154 u = manager_get_unit(m, name);
1156 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
1158 if (u->type != UNIT_SNAPSHOT)
1159 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
1161 return bus_snapshot_method_remove(bus, message, u, error);
1164 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1165 Manager *m = userdata;
1172 r = mac_selinux_access_check(message, "reload", error);
1176 r = bus_verify_reload_daemon_async(m, message, error);
1180 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1182 /* Instead of sending the reply back right away, we just
1183 * remember that we need to and then send it after the reload
1184 * is finished. That way the caller knows when the reload
1187 assert(!m->queued_message);
1188 r = sd_bus_message_new_method_return(message, &m->queued_message);
1192 m->queued_message_bus = sd_bus_ref(bus);
1193 m->exit_code = MANAGER_RELOAD;
1198 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1199 Manager *m = userdata;
1206 r = mac_selinux_access_check(message, "reload", error);
1210 r = bus_verify_reload_daemon_async(m, message, error);
1214 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1216 /* We don't send a reply back here, the client should
1217 * just wait for us disconnecting. */
1219 m->exit_code = MANAGER_REEXECUTE;
1223 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1224 Manager *m = userdata;
1231 r = mac_selinux_access_check(message, "halt", error);
1235 if (m->running_as == SYSTEMD_SYSTEM)
1236 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1238 m->exit_code = MANAGER_EXIT;
1240 return sd_bus_reply_method_return(message, NULL);
1243 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1244 Manager *m = userdata;
1251 r = mac_selinux_access_check(message, "reboot", error);
1255 if (m->running_as != SYSTEMD_SYSTEM)
1256 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1258 m->exit_code = MANAGER_REBOOT;
1260 return sd_bus_reply_method_return(message, NULL);
1263 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1264 Manager *m = userdata;
1271 r = mac_selinux_access_check(message, "halt", error);
1275 if (m->running_as != SYSTEMD_SYSTEM)
1276 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1278 m->exit_code = MANAGER_POWEROFF;
1280 return sd_bus_reply_method_return(message, NULL);
1283 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1284 Manager *m = userdata;
1291 r = mac_selinux_access_check(message, "halt", error);
1295 if (m->running_as != SYSTEMD_SYSTEM)
1296 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1298 m->exit_code = MANAGER_HALT;
1300 return sd_bus_reply_method_return(message, NULL);
1303 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1304 Manager *m = userdata;
1311 r = mac_selinux_access_check(message, "reboot", error);
1315 if (m->running_as != SYSTEMD_SYSTEM)
1316 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1318 m->exit_code = MANAGER_KEXEC;
1320 return sd_bus_reply_method_return(message, NULL);
1323 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1324 char *ri = NULL, *rt = NULL;
1325 const char *root, *init;
1326 Manager *m = userdata;
1333 r = mac_selinux_access_check(message, "reboot", error);
1337 if (m->running_as != SYSTEMD_SYSTEM)
1338 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1340 r = sd_bus_message_read(message, "ss", &root, &init);
1344 if (path_equal(root, "/") || !path_is_absolute(root))
1345 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1348 if (isempty(init)) {
1349 if (!path_is_os_tree(root))
1350 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);
1352 _cleanup_free_ char *p = NULL;
1354 if (!path_is_absolute(init))
1355 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1357 p = strappend(root, init);
1361 if (access(p, X_OK) < 0)
1362 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1369 if (!isempty(init)) {
1377 free(m->switch_root);
1378 m->switch_root = rt;
1380 free(m->switch_root_init);
1381 m->switch_root_init = ri;
1383 m->exit_code = MANAGER_SWITCH_ROOT;
1385 return sd_bus_reply_method_return(message, NULL);
1388 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1389 _cleanup_strv_free_ char **plus = NULL;
1390 Manager *m = userdata;
1397 r = mac_selinux_access_check(message, "reload", error);
1401 r = sd_bus_message_read_strv(message, &plus);
1404 if (!strv_env_is_valid(plus))
1405 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1407 r = bus_verify_set_environment_async(m, message, error);
1411 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1413 r = manager_environment_add(m, NULL, plus);
1417 return sd_bus_reply_method_return(message, NULL);
1420 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1421 _cleanup_strv_free_ char **minus = NULL;
1422 Manager *m = userdata;
1429 r = mac_selinux_access_check(message, "reload", error);
1433 r = sd_bus_message_read_strv(message, &minus);
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");
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, NULL);
1450 return sd_bus_reply_method_return(message, NULL);
1453 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1454 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1455 Manager *m = userdata;
1462 r = mac_selinux_access_check(message, "reload", error);
1466 r = sd_bus_message_read_strv(message, &minus);
1470 r = sd_bus_message_read_strv(message, &plus);
1474 if (!strv_env_name_or_assignment_is_valid(minus))
1475 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1476 if (!strv_env_is_valid(plus))
1477 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1479 r = bus_verify_set_environment_async(m, message, error);
1483 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1485 r = manager_environment_add(m, minus, plus);
1489 return sd_bus_reply_method_return(message, NULL);
1492 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1493 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1494 Manager *m = userdata;
1504 /* Anyone can call this method */
1506 r = mac_selinux_access_check(message, "status", error);
1510 r = sd_bus_message_new_method_return(message, &reply);
1514 h = hashmap_new(&string_hash_ops);
1518 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1522 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1526 HASHMAP_FOREACH(item, h, i) {
1528 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1533 unit_file_list_free(h);
1535 r = sd_bus_message_close_container(reply);
1539 return sd_bus_send(bus, reply, NULL);
1542 unit_file_list_free(h);
1546 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1547 Manager *m = userdata;
1549 UnitFileState state;
1550 UnitFileScope scope;
1557 /* Anyone can call this method */
1559 r = mac_selinux_access_check(message, "status", error);
1563 r = sd_bus_message_read(message, "s", &name);
1567 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1569 state = unit_file_get_state(scope, NULL, name);
1573 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1576 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1577 _cleanup_free_ char *default_target = NULL;
1578 Manager *m = userdata;
1579 UnitFileScope scope;
1586 /* Anyone can call this method */
1588 r = mac_selinux_access_check(message, "status", error);
1592 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1594 r = unit_file_get_default(scope, NULL, &default_target);
1598 return sd_bus_reply_method_return(message, "s", default_target);
1601 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1602 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1607 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1611 return sd_bus_send(bus, message, NULL);
1614 static int reply_unit_file_changes_and_free(
1617 sd_bus_message *message,
1618 int carries_install_info,
1619 UnitFileChange *changes,
1620 unsigned n_changes) {
1622 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1626 if (n_changes > 0) {
1627 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1629 log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
1632 r = sd_bus_message_new_method_return(message, &reply);
1636 if (carries_install_info >= 0) {
1637 r = sd_bus_message_append(reply, "b", carries_install_info);
1642 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1646 for (i = 0; i < n_changes; i++) {
1647 r = sd_bus_message_append(
1649 unit_file_change_type_to_string(changes[i].type),
1656 r = sd_bus_message_close_container(reply);
1660 return sd_bus_send(bus, reply, NULL);
1663 unit_file_changes_free(changes, n_changes);
1667 static int method_enable_unit_files_generic(
1669 sd_bus_message *message,
1672 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1673 bool carries_install_info,
1674 sd_bus_error *error) {
1676 _cleanup_strv_free_ char **l = NULL;
1677 UnitFileChange *changes = NULL;
1678 unsigned n_changes = 0;
1679 UnitFileScope scope;
1680 int runtime, force, r;
1686 r = sd_bus_message_read_strv(message, &l);
1690 r = sd_bus_message_read(message, "bb", &runtime, &force);
1694 r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
1698 r = bus_verify_manage_unit_files_async(m, message, error);
1702 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1704 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1706 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1710 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1713 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1714 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1717 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1718 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1721 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1722 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1725 static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1726 return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1729 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1730 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
1733 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1734 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1737 static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1739 _cleanup_strv_free_ char **l = NULL;
1740 UnitFileChange *changes = NULL;
1741 unsigned n_changes = 0;
1742 Manager *m = userdata;
1743 UnitFilePresetMode mm;
1744 UnitFileScope scope;
1745 int runtime, force, r;
1752 r = sd_bus_message_read_strv(message, &l);
1756 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1761 mm = UNIT_FILE_PRESET_FULL;
1763 mm = unit_file_preset_mode_from_string(mode);
1768 r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1772 r = bus_verify_manage_unit_files_async(m, message, error);
1776 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1778 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1780 r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
1784 return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
1787 static int method_disable_unit_files_generic(
1789 sd_bus_message *message,
1792 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1793 sd_bus_error *error) {
1795 _cleanup_strv_free_ char **l = NULL;
1796 UnitFileChange *changes = NULL;
1797 unsigned n_changes = 0;
1798 UnitFileScope scope;
1805 r = mac_selinux_access_check(message, verb, error);
1809 r = sd_bus_message_read_strv(message, &l);
1813 r = sd_bus_message_read(message, "b", &runtime);
1817 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1819 r = bus_verify_manage_unit_files_async(m, message, error);
1823 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1825 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1829 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1832 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1833 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1836 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1837 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1840 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1841 UnitFileChange *changes = NULL;
1842 unsigned n_changes = 0;
1843 Manager *m = userdata;
1844 UnitFileScope scope;
1852 r = mac_selinux_access_check(message, "enable", error);
1856 r = sd_bus_message_read(message, "sb", &name, &force);
1860 r = bus_verify_manage_unit_files_async(m, message, error);
1864 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1866 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1868 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1872 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1875 static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1876 UnitFileChange *changes = NULL;
1877 unsigned n_changes = 0;
1878 Manager *m = userdata;
1879 UnitFilePresetMode mm;
1880 UnitFileScope scope;
1882 int force, runtime, r;
1888 r = mac_selinux_access_check(message, "enable", error);
1892 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1897 mm = UNIT_FILE_PRESET_FULL;
1899 mm = unit_file_preset_mode_from_string(mode);
1904 r = bus_verify_manage_unit_files_async(m, message, error);
1908 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1910 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1912 r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
1916 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1919 static int method_add_dependency_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1920 _cleanup_strv_free_ char **l = NULL;
1921 Manager *m = userdata;
1922 UnitFileChange *changes = NULL;
1923 unsigned n_changes = 0;
1924 UnitFileScope scope;
1925 int runtime, force, r;
1934 r = bus_verify_manage_unit_files_async(m, message, error);
1938 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1940 r = sd_bus_message_read_strv(message, &l);
1944 r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
1948 dep = unit_dependency_from_string(type);
1952 r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1956 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1958 r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
1962 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1965 const sd_bus_vtable bus_manager_vtable[] = {
1966 SD_BUS_VTABLE_START(0),
1968 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1969 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1970 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1971 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1972 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1973 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1974 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1975 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1976 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1977 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1978 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1979 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1980 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1981 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1982 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1983 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1984 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1985 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1986 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1987 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1988 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1989 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1990 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1991 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1992 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1993 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1994 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1995 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1996 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1997 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1998 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1999 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
2000 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
2001 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
2002 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
2004 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2005 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2006 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2007 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2008 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
2009 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2010 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2011 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2012 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2013 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2014 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2015 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2016 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2017 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
2018 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2019 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
2020 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
2021 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2022 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
2023 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
2024 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
2025 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2026 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2027 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2028 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
2029 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2030 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2031 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
2032 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
2033 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
2034 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2035 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2036 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2037 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2038 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2039 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2040 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2041 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2042 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2043 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
2044 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2045 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2046 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2047 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2048 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2049 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2050 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2051 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2052 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2053 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2054 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2055 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2057 SD_BUS_SIGNAL("UnitNew", "so", 0),
2058 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2059 SD_BUS_SIGNAL("JobNew", "uos", 0),
2060 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2061 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2062 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2063 SD_BUS_SIGNAL("Reloading", "b", 0),
2068 static int send_finished(sd_bus *bus, void *userdata) {
2069 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2070 usec_t *times = userdata;
2076 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2080 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2084 return sd_bus_send(bus, message, NULL);
2087 void bus_manager_send_finished(
2089 usec_t firmware_usec,
2093 usec_t userspace_usec,
2094 usec_t total_usec) {
2100 r = bus_foreach_bus(
2113 log_debug_errno(r, "Failed to send finished signal: %m");
2116 static int send_reloading(sd_bus *bus, void *userdata) {
2117 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2122 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2126 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2130 return sd_bus_send(bus, message, NULL);
2133 void bus_manager_send_reloading(Manager *m, bool active) {
2138 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2140 log_debug_errno(r, "Failed to send reloading signal: %m");
2143 static int send_changed_signal(sd_bus *bus, void *userdata) {
2146 return sd_bus_emit_properties_changed_strv(bus,
2147 "/org/freedesktop/systemd1",
2148 "org.freedesktop.systemd1.Manager",
2152 void bus_manager_send_change_signal(Manager *m) {
2157 r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
2159 log_debug_errno(r, "Failed to send manager change signal: %m");