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) {
678 r = sd_bus_message_read(message, "s", &name);
682 r = transient_unit_from_message(m, message, name, &u, error);
683 if (r < 0 && r != -EEXIST)
692 r = sd_bus_message_exit_container(message);
699 r = sd_bus_message_exit_container(message);
706 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
707 const char *name, *smode;
708 Manager *m = userdata;
718 r = mac_selinux_access_check(message, "start", error);
722 r = sd_bus_message_read(message, "ss", &name, &smode);
726 t = unit_name_to_type(name);
728 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
730 if (!unit_vtable[t]->can_transient)
731 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
733 mode = job_mode_from_string(smode);
735 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
737 r = bus_verify_manage_units_async(m, message, error);
741 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
743 r = transient_unit_from_message(m, message, name, &u, error);
747 r = transient_aux_units_from_message(m, message, error);
751 /* And load this stub fully */
756 manager_dispatch_load_queue(m);
758 /* Finally, start it */
759 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
762 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
763 _cleanup_free_ char *path = NULL;
764 Manager *m = userdata;
773 /* Anyone can call this method */
775 r = sd_bus_message_read(message, "u", &id);
779 j = manager_get_job(m, id);
781 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
783 r = mac_selinux_unit_access_check(j->unit, message, "status", error);
787 path = job_dbus_path(j);
791 return sd_bus_reply_method_return(message, "o", path);
794 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
795 Manager *m = userdata;
804 r = sd_bus_message_read(message, "u", &id);
808 j = manager_get_job(m, id);
810 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
812 return bus_job_method_cancel(bus, message, j, error);
815 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
816 Manager *m = userdata;
823 r = mac_selinux_access_check(message, "reload", error);
827 r = bus_verify_manage_units_async(m, message, error);
831 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
833 manager_clear_jobs(m);
835 return sd_bus_reply_method_return(message, NULL);
838 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
839 Manager *m = userdata;
846 r = mac_selinux_access_check(message, "reload", error);
850 r = bus_verify_manage_units_async(m, message, error);
854 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
856 manager_reset_failed(m);
858 return sd_bus_reply_method_return(message, NULL);
861 static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
862 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
863 Manager *m = userdata;
873 /* Anyone can call this method */
875 r = mac_selinux_access_check(message, "status", error);
879 r = sd_bus_message_new_method_return(message, &reply);
883 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
887 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
888 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
894 following = unit_following(u);
896 if (!strv_isempty(states) &&
897 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
898 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
899 !strv_contains(states, unit_sub_state_to_string(u)))
902 unit_path = unit_dbus_path(u);
907 job_path = job_dbus_path(u->job);
912 r = sd_bus_message_append(
913 reply, "(ssssssouso)",
916 unit_load_state_to_string(u->load_state),
917 unit_active_state_to_string(unit_active_state(u)),
918 unit_sub_state_to_string(u),
919 following ? following->id : "",
921 u->job ? u->job->id : 0,
922 u->job ? job_type_to_string(u->job->type) : "",
923 job_path ? job_path : "/");
928 r = sd_bus_message_close_container(reply);
932 return sd_bus_send(bus, reply, NULL);
935 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
936 return list_units_filtered(bus, message, userdata, error, NULL);
939 static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
940 _cleanup_strv_free_ char **states = NULL;
943 r = sd_bus_message_read_strv(message, &states);
947 return list_units_filtered(bus, message, userdata, error, states);
950 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
951 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
952 Manager *m = userdata;
961 /* Anyone can call this method */
963 r = mac_selinux_access_check(message, "status", error);
967 r = sd_bus_message_new_method_return(message, &reply);
971 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
975 HASHMAP_FOREACH(j, m->jobs, i) {
976 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
978 job_path = job_dbus_path(j);
982 unit_path = unit_dbus_path(j->unit);
986 r = sd_bus_message_append(
990 job_type_to_string(j->type),
991 job_state_to_string(j->state),
998 r = sd_bus_message_close_container(reply);
1002 return sd_bus_send(bus, reply, NULL);
1005 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1006 Manager *m = userdata;
1013 /* Anyone can call this method */
1015 r = mac_selinux_access_check(message, "status", error);
1019 if (bus == m->api_bus) {
1021 /* Note that direct bus connection subscribe by
1022 * default, we only track peers on the API bus here */
1024 if (!m->subscribed) {
1025 r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
1030 r = sd_bus_track_add_sender(m->subscribed, message);
1034 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1037 return sd_bus_reply_method_return(message, NULL);
1040 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1041 Manager *m = userdata;
1048 /* Anyone can call this method */
1050 r = mac_selinux_access_check(message, "status", error);
1054 if (bus == m->api_bus) {
1055 r = sd_bus_track_remove_sender(m->subscribed, message);
1059 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1062 return sd_bus_reply_method_return(message, NULL);
1065 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1066 _cleanup_free_ char *dump = NULL;
1067 _cleanup_fclose_ FILE *f = NULL;
1068 Manager *m = userdata;
1076 /* Anyone can call this method */
1078 r = mac_selinux_access_check(message, "status", error);
1082 f = open_memstream(&dump, &size);
1086 manager_dump_units(m, f, NULL);
1087 manager_dump_jobs(m, f, NULL);
1094 return sd_bus_reply_method_return(message, "s", dump);
1097 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1098 _cleanup_free_ char *path = NULL;
1099 Manager *m = userdata;
1109 r = mac_selinux_access_check(message, "start", error);
1113 r = sd_bus_message_read(message, "sb", &name, &cleanup);
1120 r = bus_verify_manage_units_async(m, message, error);
1124 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1126 r = snapshot_create(m, name, cleanup, error, &s);
1130 path = unit_dbus_path(UNIT(s));
1134 return sd_bus_reply_method_return(message, "o", path);
1137 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1138 Manager *m = userdata;
1147 r = sd_bus_message_read(message, "s", &name);
1151 u = manager_get_unit(m, name);
1153 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
1155 if (u->type != UNIT_SNAPSHOT)
1156 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
1158 return bus_snapshot_method_remove(bus, message, u, error);
1161 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1162 Manager *m = userdata;
1169 r = mac_selinux_access_check(message, "reload", error);
1173 r = bus_verify_reload_daemon_async(m, message, error);
1177 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1179 /* Instead of sending the reply back right away, we just
1180 * remember that we need to and then send it after the reload
1181 * is finished. That way the caller knows when the reload
1184 assert(!m->queued_message);
1185 r = sd_bus_message_new_method_return(message, &m->queued_message);
1189 m->queued_message_bus = sd_bus_ref(bus);
1190 m->exit_code = MANAGER_RELOAD;
1195 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1196 Manager *m = userdata;
1203 r = mac_selinux_access_check(message, "reload", error);
1207 r = bus_verify_reload_daemon_async(m, message, error);
1211 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1213 /* We don't send a reply back here, the client should
1214 * just wait for us disconnecting. */
1216 m->exit_code = MANAGER_REEXECUTE;
1220 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1221 Manager *m = userdata;
1228 r = mac_selinux_access_check(message, "halt", error);
1232 if (m->running_as == SYSTEMD_SYSTEM)
1233 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1235 m->exit_code = MANAGER_EXIT;
1237 return sd_bus_reply_method_return(message, NULL);
1240 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1241 Manager *m = userdata;
1248 r = mac_selinux_access_check(message, "reboot", error);
1252 if (m->running_as != SYSTEMD_SYSTEM)
1253 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1255 m->exit_code = MANAGER_REBOOT;
1257 return sd_bus_reply_method_return(message, NULL);
1260 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1261 Manager *m = userdata;
1268 r = mac_selinux_access_check(message, "halt", error);
1272 if (m->running_as != SYSTEMD_SYSTEM)
1273 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1275 m->exit_code = MANAGER_POWEROFF;
1277 return sd_bus_reply_method_return(message, NULL);
1280 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1281 Manager *m = userdata;
1288 r = mac_selinux_access_check(message, "halt", error);
1292 if (m->running_as != SYSTEMD_SYSTEM)
1293 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1295 m->exit_code = MANAGER_HALT;
1297 return sd_bus_reply_method_return(message, NULL);
1300 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1301 Manager *m = userdata;
1308 r = mac_selinux_access_check(message, "reboot", error);
1312 if (m->running_as != SYSTEMD_SYSTEM)
1313 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1315 m->exit_code = MANAGER_KEXEC;
1317 return sd_bus_reply_method_return(message, NULL);
1320 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1321 char *ri = NULL, *rt = NULL;
1322 const char *root, *init;
1323 Manager *m = userdata;
1330 r = mac_selinux_access_check(message, "reboot", error);
1334 if (m->running_as != SYSTEMD_SYSTEM)
1335 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1337 r = sd_bus_message_read(message, "ss", &root, &init);
1341 if (path_equal(root, "/") || !path_is_absolute(root))
1342 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1345 if (isempty(init)) {
1346 if (!path_is_os_tree(root))
1347 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);
1349 _cleanup_free_ char *p = NULL;
1351 if (!path_is_absolute(init))
1352 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1354 p = strappend(root, init);
1358 if (access(p, X_OK) < 0)
1359 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1366 if (!isempty(init)) {
1374 free(m->switch_root);
1375 m->switch_root = rt;
1377 free(m->switch_root_init);
1378 m->switch_root_init = ri;
1380 m->exit_code = MANAGER_SWITCH_ROOT;
1382 return sd_bus_reply_method_return(message, NULL);
1385 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1386 _cleanup_strv_free_ char **plus = NULL;
1387 Manager *m = userdata;
1394 r = mac_selinux_access_check(message, "reload", error);
1398 r = sd_bus_message_read_strv(message, &plus);
1401 if (!strv_env_is_valid(plus))
1402 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment 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, NULL, plus);
1414 return sd_bus_reply_method_return(message, NULL);
1417 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1418 _cleanup_strv_free_ char **minus = NULL;
1419 Manager *m = userdata;
1426 r = mac_selinux_access_check(message, "reload", error);
1430 r = sd_bus_message_read_strv(message, &minus);
1434 if (!strv_env_name_or_assignment_is_valid(minus))
1435 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1437 r = bus_verify_set_environment_async(m, message, error);
1441 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1443 r = manager_environment_add(m, minus, NULL);
1447 return sd_bus_reply_method_return(message, NULL);
1450 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1451 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1452 Manager *m = userdata;
1459 r = mac_selinux_access_check(message, "reload", error);
1463 r = sd_bus_message_read_strv(message, &minus);
1467 r = sd_bus_message_read_strv(message, &plus);
1471 if (!strv_env_name_or_assignment_is_valid(minus))
1472 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1473 if (!strv_env_is_valid(plus))
1474 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1476 r = bus_verify_set_environment_async(m, message, error);
1480 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1482 r = manager_environment_add(m, minus, plus);
1486 return sd_bus_reply_method_return(message, NULL);
1489 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1490 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1491 Manager *m = userdata;
1501 /* Anyone can call this method */
1503 r = mac_selinux_access_check(message, "status", error);
1507 r = sd_bus_message_new_method_return(message, &reply);
1511 h = hashmap_new(&string_hash_ops);
1515 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1519 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1523 HASHMAP_FOREACH(item, h, i) {
1525 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1530 unit_file_list_free(h);
1532 r = sd_bus_message_close_container(reply);
1536 return sd_bus_send(bus, reply, NULL);
1539 unit_file_list_free(h);
1543 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1544 Manager *m = userdata;
1546 UnitFileState state;
1547 UnitFileScope scope;
1554 /* Anyone can call this method */
1556 r = mac_selinux_access_check(message, "status", error);
1560 r = sd_bus_message_read(message, "s", &name);
1564 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1566 state = unit_file_get_state(scope, NULL, name);
1570 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1573 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1574 _cleanup_free_ char *default_target = NULL;
1575 Manager *m = userdata;
1576 UnitFileScope scope;
1583 /* Anyone can call this method */
1585 r = mac_selinux_access_check(message, "status", error);
1589 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1591 r = unit_file_get_default(scope, NULL, &default_target);
1595 return sd_bus_reply_method_return(message, "s", default_target);
1598 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1599 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1604 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1608 return sd_bus_send(bus, message, NULL);
1611 static int reply_unit_file_changes_and_free(
1614 sd_bus_message *message,
1615 int carries_install_info,
1616 UnitFileChange *changes,
1617 unsigned n_changes) {
1619 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1623 if (n_changes > 0) {
1624 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1626 log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
1629 r = sd_bus_message_new_method_return(message, &reply);
1633 if (carries_install_info >= 0) {
1634 r = sd_bus_message_append(reply, "b", carries_install_info);
1639 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1643 for (i = 0; i < n_changes; i++) {
1644 r = sd_bus_message_append(
1646 unit_file_change_type_to_string(changes[i].type),
1653 r = sd_bus_message_close_container(reply);
1657 return sd_bus_send(bus, reply, NULL);
1660 unit_file_changes_free(changes, n_changes);
1664 static int method_enable_unit_files_generic(
1666 sd_bus_message *message,
1669 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1670 bool carries_install_info,
1671 sd_bus_error *error) {
1673 _cleanup_strv_free_ char **l = NULL;
1674 UnitFileChange *changes = NULL;
1675 unsigned n_changes = 0;
1676 UnitFileScope scope;
1677 int runtime, force, r;
1683 r = sd_bus_message_read_strv(message, &l);
1687 r = sd_bus_message_read(message, "bb", &runtime, &force);
1691 r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
1695 r = bus_verify_manage_unit_files_async(m, message, error);
1699 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1701 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1703 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1707 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1710 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1711 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1714 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1715 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1718 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1719 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1722 static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1723 return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1726 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1727 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
1730 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1731 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1734 static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1736 _cleanup_strv_free_ char **l = NULL;
1737 UnitFileChange *changes = NULL;
1738 unsigned n_changes = 0;
1739 Manager *m = userdata;
1740 UnitFilePresetMode mm;
1741 UnitFileScope scope;
1742 int runtime, force, r;
1749 r = sd_bus_message_read_strv(message, &l);
1753 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1758 mm = UNIT_FILE_PRESET_FULL;
1760 mm = unit_file_preset_mode_from_string(mode);
1765 r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1769 r = bus_verify_manage_unit_files_async(m, message, error);
1773 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1775 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1777 r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
1781 return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
1784 static int method_disable_unit_files_generic(
1786 sd_bus_message *message,
1789 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1790 sd_bus_error *error) {
1792 _cleanup_strv_free_ char **l = NULL;
1793 UnitFileChange *changes = NULL;
1794 unsigned n_changes = 0;
1795 UnitFileScope scope;
1802 r = mac_selinux_access_check(message, verb, error);
1806 r = sd_bus_message_read_strv(message, &l);
1810 r = sd_bus_message_read(message, "b", &runtime);
1814 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1816 r = bus_verify_manage_unit_files_async(m, message, error);
1820 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1822 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1826 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1829 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1830 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1833 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1834 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1837 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1838 UnitFileChange *changes = NULL;
1839 unsigned n_changes = 0;
1840 Manager *m = userdata;
1841 UnitFileScope scope;
1849 r = mac_selinux_access_check(message, "enable", error);
1853 r = sd_bus_message_read(message, "sb", &name, &force);
1857 r = bus_verify_manage_unit_files_async(m, message, error);
1861 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1863 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1865 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1869 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1872 static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1873 UnitFileChange *changes = NULL;
1874 unsigned n_changes = 0;
1875 Manager *m = userdata;
1876 UnitFilePresetMode mm;
1877 UnitFileScope scope;
1879 int force, runtime, r;
1885 r = mac_selinux_access_check(message, "enable", error);
1889 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1894 mm = UNIT_FILE_PRESET_FULL;
1896 mm = unit_file_preset_mode_from_string(mode);
1901 r = bus_verify_manage_unit_files_async(m, message, error);
1905 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1907 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1909 r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
1913 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1916 static int method_add_dependency_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1917 _cleanup_strv_free_ char **l = NULL;
1918 Manager *m = userdata;
1919 UnitFileChange *changes = NULL;
1920 unsigned n_changes = 0;
1921 UnitFileScope scope;
1922 int runtime, force, r;
1931 r = bus_verify_manage_unit_files_async(m, message, error);
1935 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1937 r = sd_bus_message_read_strv(message, &l);
1941 r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
1945 dep = unit_dependency_from_string(type);
1949 r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1953 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1955 r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
1959 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1962 const sd_bus_vtable bus_manager_vtable[] = {
1963 SD_BUS_VTABLE_START(0),
1965 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1966 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1967 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1968 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1969 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1970 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1971 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1972 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1973 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1974 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1975 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1976 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1977 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1978 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1979 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1980 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1981 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1982 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1983 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1984 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1985 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1986 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1987 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1988 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1989 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1990 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1991 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1992 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1993 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1994 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1995 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1996 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1997 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1998 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1999 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
2001 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2002 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2003 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2004 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2005 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
2006 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2007 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2008 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2009 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2010 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2011 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2012 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2013 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2014 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
2015 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2016 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
2017 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
2018 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2019 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
2020 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
2021 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
2022 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2023 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2024 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2025 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
2026 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2027 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2028 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
2029 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
2030 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
2031 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2032 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2033 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2034 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2035 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2036 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2037 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2038 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2039 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2040 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
2041 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2042 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2043 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2044 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2045 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2046 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2047 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2048 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2049 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2050 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2051 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2052 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2054 SD_BUS_SIGNAL("UnitNew", "so", 0),
2055 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2056 SD_BUS_SIGNAL("JobNew", "uos", 0),
2057 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2058 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2059 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2060 SD_BUS_SIGNAL("Reloading", "b", 0),
2065 static int send_finished(sd_bus *bus, void *userdata) {
2066 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2067 usec_t *times = userdata;
2073 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2077 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2081 return sd_bus_send(bus, message, NULL);
2084 void bus_manager_send_finished(
2086 usec_t firmware_usec,
2090 usec_t userspace_usec,
2091 usec_t total_usec) {
2097 r = bus_foreach_bus(
2110 log_debug_errno(r, "Failed to send finished signal: %m");
2113 static int send_reloading(sd_bus *bus, void *userdata) {
2114 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2119 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2123 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2127 return sd_bus_send(bus, message, NULL);
2130 void bus_manager_send_reloading(Manager *m, bool active) {
2135 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2137 log_debug_errno(r, "Failed to send reloading signal: %m");
2140 static int send_changed_signal(sd_bus *bus, void *userdata) {
2143 return sd_bus_emit_properties_changed_strv(bus,
2144 "/org/freedesktop/systemd1",
2145 "org.freedesktop.systemd1.Manager",
2149 void bus_manager_send_change_signal(Manager *m) {
2154 r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
2156 log_debug_errno(r, "Failed to send manager change signal: %m");