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);
362 u = manager_get_unit(m, name);
364 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
366 r = mac_selinux_unit_access_check(u, message, "status", error);
370 path = unit_dbus_path(u);
374 return sd_bus_reply_method_return(message, "o", path);
377 static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
378 _cleanup_free_ char *path = NULL;
379 Manager *m = userdata;
388 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
390 /* Anyone can call this method */
392 r = sd_bus_message_read(message, "u", &pid);
397 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
399 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
403 r = sd_bus_creds_get_pid(creds, &pid);
408 u = manager_get_unit_by_pid(m, pid);
410 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
412 r = mac_selinux_unit_access_check(u, message, "status", error);
416 path = unit_dbus_path(u);
420 return sd_bus_reply_method_return(message, "o", path);
423 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
424 _cleanup_free_ char *path = NULL;
425 Manager *m = userdata;
434 /* Anyone can call this method */
436 r = sd_bus_message_read(message, "s", &name);
440 r = manager_load_unit(m, name, NULL, error, &u);
444 r = mac_selinux_unit_access_check(u, message, "status", error);
448 path = unit_dbus_path(u);
452 return sd_bus_reply_method_return(message, "o", path);
455 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) {
464 r = bus_verify_manage_unit_async(m, message, error);
468 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
470 r = sd_bus_message_read(message, "s", &name);
474 r = manager_load_unit(m, name, NULL, error, &u);
478 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
481 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
482 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
485 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
486 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
489 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
490 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
493 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
494 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
497 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
498 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
501 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
502 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
505 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
506 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
509 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
510 Manager *m = userdata;
511 const char *old_name;
519 r = bus_verify_manage_unit_async(m, message, error);
523 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
525 r = sd_bus_message_read(message, "s", &old_name);
529 u = manager_get_unit(m, old_name);
530 if (!u || !u->job || u->job->type != JOB_START)
531 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
533 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
536 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
537 Manager *m = userdata;
546 /* Like bus_verify_manage_unit_async(), but uses CAP_SYS_KILL */
547 r = bus_verify_manage_unit_async_for_kill(m, message, error);
551 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
553 r = sd_bus_message_read(message, "s", &name);
557 u = manager_get_unit(m, name);
559 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
561 return bus_unit_method_kill(bus, message, u, error);
564 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
565 Manager *m = userdata;
574 r = bus_verify_manage_unit_async(m, message, error);
578 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
580 r = sd_bus_message_read(message, "s", &name);
584 u = manager_get_unit(m, name);
586 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
588 return bus_unit_method_reset_failed(bus, message, u, error);
591 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
592 Manager *m = userdata;
601 r = bus_verify_manage_unit_async(m, message, error);
605 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
607 r = sd_bus_message_read(message, "s", &name);
611 u = manager_get_unit(m, name);
613 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
615 return bus_unit_method_set_properties(bus, message, u, error);
618 static int transient_unit_from_message(
620 sd_bus_message *message,
623 sd_bus_error *error) {
632 r = manager_load_unit(m, name, NULL, error, &u);
636 if (u->load_state != UNIT_NOT_FOUND ||
637 set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
638 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
640 /* OK, the unit failed to load and is unreferenced, now let's
641 * fill in the transient data instead */
642 r = unit_make_transient(u);
646 /* Set our properties */
647 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
656 static int transient_aux_units_from_message(
658 sd_bus_message *message,
659 sd_bus_error *error) {
668 r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
672 while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
676 r = sd_bus_message_read(message, "s", &name);
680 r = transient_unit_from_message(m, message, name, &u, error);
681 if (r < 0 && r != -EEXIST)
690 r = sd_bus_message_exit_container(message);
697 r = sd_bus_message_exit_container(message);
704 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
705 const char *name, *smode;
706 Manager *m = userdata;
716 r = bus_verify_manage_unit_async(m, message, error);
720 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
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 = mac_selinux_access_check(message, "start", error);
741 r = transient_unit_from_message(m, message, name, &u, error);
745 r = transient_aux_units_from_message(m, message, error);
749 /* And load this stub fully */
754 manager_dispatch_load_queue(m);
756 /* Finally, start it */
757 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
760 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
761 _cleanup_free_ char *path = NULL;
762 Manager *m = userdata;
771 /* Anyone can call this method */
773 r = sd_bus_message_read(message, "u", &id);
777 j = manager_get_job(m, id);
779 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
781 r = mac_selinux_unit_access_check(j->unit, message, "status", error);
785 path = job_dbus_path(j);
789 return sd_bus_reply_method_return(message, "o", path);
792 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
793 Manager *m = userdata;
802 r = sd_bus_message_read(message, "u", &id);
806 j = manager_get_job(m, id);
808 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
810 return bus_job_method_cancel(bus, message, j, error);
813 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
814 Manager *m = userdata;
821 r = mac_selinux_access_check(message, "reboot", error);
825 manager_clear_jobs(m);
827 return sd_bus_reply_method_return(message, NULL);
830 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
831 Manager *m = userdata;
838 r = mac_selinux_access_check(message, "reload", error);
842 manager_reset_failed(m);
844 return sd_bus_reply_method_return(message, NULL);
847 static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
848 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
849 Manager *m = userdata;
859 /* Anyone can call this method */
861 r = mac_selinux_access_check(message, "status", error);
865 r = sd_bus_message_new_method_return(message, &reply);
869 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
873 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
874 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
880 following = unit_following(u);
882 if (!strv_isempty(states) &&
883 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
884 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
885 !strv_contains(states, unit_sub_state_to_string(u)))
888 unit_path = unit_dbus_path(u);
893 job_path = job_dbus_path(u->job);
898 r = sd_bus_message_append(
899 reply, "(ssssssouso)",
902 unit_load_state_to_string(u->load_state),
903 unit_active_state_to_string(unit_active_state(u)),
904 unit_sub_state_to_string(u),
905 following ? following->id : "",
907 u->job ? u->job->id : 0,
908 u->job ? job_type_to_string(u->job->type) : "",
909 job_path ? job_path : "/");
914 r = sd_bus_message_close_container(reply);
918 return sd_bus_send(bus, reply, NULL);
921 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
922 return list_units_filtered(bus, message, userdata, error, NULL);
925 static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
926 _cleanup_strv_free_ char **states = NULL;
929 r = sd_bus_message_read_strv(message, &states);
933 return list_units_filtered(bus, message, userdata, error, states);
936 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
937 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
938 Manager *m = userdata;
947 /* Anyone can call this method */
949 r = mac_selinux_access_check(message, "status", error);
953 r = sd_bus_message_new_method_return(message, &reply);
957 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
961 HASHMAP_FOREACH(j, m->jobs, i) {
962 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
964 job_path = job_dbus_path(j);
968 unit_path = unit_dbus_path(j->unit);
972 r = sd_bus_message_append(
976 job_type_to_string(j->type),
977 job_state_to_string(j->state),
984 r = sd_bus_message_close_container(reply);
988 return sd_bus_send(bus, reply, NULL);
991 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
992 Manager *m = userdata;
999 /* Anyone can call this method */
1001 r = mac_selinux_access_check(message, "status", error);
1005 if (bus == m->api_bus) {
1007 /* Note that direct bus connection subscribe by
1008 * default, we only track peers on the API bus here */
1010 if (!m->subscribed) {
1011 r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
1016 r = sd_bus_track_add_sender(m->subscribed, message);
1020 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1023 return sd_bus_reply_method_return(message, NULL);
1026 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1027 Manager *m = userdata;
1034 /* Anyone can call this method */
1036 r = mac_selinux_access_check(message, "status", error);
1040 if (bus == m->api_bus) {
1041 r = sd_bus_track_remove_sender(m->subscribed, message);
1045 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1048 return sd_bus_reply_method_return(message, NULL);
1051 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1052 _cleanup_free_ char *dump = NULL;
1053 _cleanup_fclose_ FILE *f = NULL;
1054 Manager *m = userdata;
1062 /* Anyone can call this method */
1064 r = mac_selinux_access_check(message, "status", error);
1068 f = open_memstream(&dump, &size);
1072 manager_dump_units(m, f, NULL);
1073 manager_dump_jobs(m, f, NULL);
1080 return sd_bus_reply_method_return(message, "s", dump);
1083 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1084 _cleanup_free_ char *path = NULL;
1085 Manager *m = userdata;
1095 r = mac_selinux_access_check(message, "start", error);
1099 r = sd_bus_message_read(message, "sb", &name, &cleanup);
1106 r = snapshot_create(m, name, cleanup, error, &s);
1110 path = unit_dbus_path(UNIT(s));
1114 return sd_bus_reply_method_return(message, "o", path);
1117 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1118 Manager *m = userdata;
1127 r = mac_selinux_access_check(message, "stop", error);
1131 r = sd_bus_message_read(message, "s", &name);
1135 u = manager_get_unit(m, name);
1137 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
1139 if (u->type != UNIT_SNAPSHOT)
1140 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
1142 return bus_snapshot_method_remove(bus, message, u, error);
1145 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1146 Manager *m = userdata;
1153 r = bus_verify_reload_daemon_async(m, message, error);
1157 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1159 r = mac_selinux_access_check(message, "reload", error);
1163 /* Instead of sending the reply back right away, we just
1164 * remember that we need to and then send it after the reload
1165 * is finished. That way the caller knows when the reload
1168 assert(!m->queued_message);
1169 r = sd_bus_message_new_method_return(message, &m->queued_message);
1173 m->queued_message_bus = sd_bus_ref(bus);
1174 m->exit_code = MANAGER_RELOAD;
1179 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1180 Manager *m = userdata;
1187 r = bus_verify_reload_daemon_async(m, message, error);
1191 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1193 r = mac_selinux_access_check(message, "reload", error);
1197 /* We don't send a reply back here, the client should
1198 * just wait for us disconnecting. */
1200 m->exit_code = MANAGER_REEXECUTE;
1204 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1205 Manager *m = userdata;
1212 r = mac_selinux_access_check(message, "halt", error);
1216 if (m->running_as == SYSTEMD_SYSTEM)
1217 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1219 m->exit_code = MANAGER_EXIT;
1221 return sd_bus_reply_method_return(message, NULL);
1224 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1225 Manager *m = userdata;
1232 r = mac_selinux_access_check(message, "reboot", error);
1236 if (m->running_as != SYSTEMD_SYSTEM)
1237 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1239 m->exit_code = MANAGER_REBOOT;
1241 return sd_bus_reply_method_return(message, NULL);
1245 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1246 Manager *m = userdata;
1253 r = mac_selinux_access_check(message, "halt", error);
1257 if (m->running_as != SYSTEMD_SYSTEM)
1258 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1260 m->exit_code = MANAGER_POWEROFF;
1262 return sd_bus_reply_method_return(message, NULL);
1265 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1266 Manager *m = userdata;
1273 r = mac_selinux_access_check(message, "halt", error);
1277 if (m->running_as != SYSTEMD_SYSTEM)
1278 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1280 m->exit_code = MANAGER_HALT;
1282 return sd_bus_reply_method_return(message, NULL);
1285 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1286 Manager *m = userdata;
1293 r = mac_selinux_access_check(message, "reboot", error);
1297 if (m->running_as != SYSTEMD_SYSTEM)
1298 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1300 m->exit_code = MANAGER_KEXEC;
1302 return sd_bus_reply_method_return(message, NULL);
1305 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1306 char *ri = NULL, *rt = NULL;
1307 const char *root, *init;
1308 Manager *m = userdata;
1315 r = mac_selinux_access_check(message, "reboot", error);
1319 if (m->running_as != SYSTEMD_SYSTEM)
1320 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1322 r = sd_bus_message_read(message, "ss", &root, &init);
1326 if (path_equal(root, "/") || !path_is_absolute(root))
1327 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1330 if (isempty(init)) {
1331 if (!path_is_os_tree(root))
1332 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);
1334 _cleanup_free_ char *p = NULL;
1336 if (!path_is_absolute(init))
1337 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1339 p = strappend(root, init);
1343 if (access(p, X_OK) < 0)
1344 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1351 if (!isempty(init)) {
1359 free(m->switch_root);
1360 m->switch_root = rt;
1362 free(m->switch_root_init);
1363 m->switch_root_init = ri;
1365 m->exit_code = MANAGER_SWITCH_ROOT;
1367 return sd_bus_reply_method_return(message, NULL);
1370 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1371 _cleanup_strv_free_ char **plus = NULL;
1372 Manager *m = userdata;
1379 r = mac_selinux_access_check(message, "reload", error);
1383 r = sd_bus_message_read_strv(message, &plus);
1386 if (!strv_env_is_valid(plus))
1387 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1389 r = manager_environment_add(m, NULL, plus);
1393 return sd_bus_reply_method_return(message, NULL);
1396 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1397 _cleanup_strv_free_ char **minus = NULL;
1398 Manager *m = userdata;
1405 r = mac_selinux_access_check(message, "reload", error);
1409 r = sd_bus_message_read_strv(message, &minus);
1413 if (!strv_env_name_or_assignment_is_valid(minus))
1414 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1416 r = manager_environment_add(m, minus, NULL);
1420 return sd_bus_reply_method_return(message, NULL);
1423 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1424 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1425 Manager *m = userdata;
1432 r = mac_selinux_access_check(message, "reload", error);
1436 r = sd_bus_message_read_strv(message, &minus);
1440 r = sd_bus_message_read_strv(message, &plus);
1444 if (!strv_env_name_or_assignment_is_valid(minus))
1445 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1446 if (!strv_env_is_valid(plus))
1447 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1449 r = manager_environment_add(m, minus, plus);
1453 return sd_bus_reply_method_return(message, NULL);
1456 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1457 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1458 Manager *m = userdata;
1468 /* Anyone can call this method */
1470 r = mac_selinux_access_check(message, "status", error);
1474 r = sd_bus_message_new_method_return(message, &reply);
1478 h = hashmap_new(&string_hash_ops);
1482 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1486 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1490 HASHMAP_FOREACH(item, h, i) {
1492 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1497 unit_file_list_free(h);
1499 r = sd_bus_message_close_container(reply);
1503 return sd_bus_send(bus, reply, NULL);
1506 unit_file_list_free(h);
1510 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1511 Manager *m = userdata;
1513 UnitFileState state;
1514 UnitFileScope scope;
1521 /* Anyone can call this method */
1523 r = mac_selinux_access_check(message, "status", error);
1527 r = sd_bus_message_read(message, "s", &name);
1531 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1533 state = unit_file_get_state(scope, NULL, name);
1537 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1540 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1541 _cleanup_free_ char *default_target = NULL;
1542 Manager *m = userdata;
1543 UnitFileScope scope;
1550 /* Anyone can call this method */
1552 r = mac_selinux_access_check(message, "status", error);
1556 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1558 r = unit_file_get_default(scope, NULL, &default_target);
1562 return sd_bus_reply_method_return(message, "s", default_target);
1565 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1566 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1571 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1575 return sd_bus_send(bus, message, NULL);
1578 static int reply_unit_file_changes_and_free(
1581 sd_bus_message *message,
1582 int carries_install_info,
1583 UnitFileChange *changes,
1584 unsigned n_changes) {
1586 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1590 if (n_changes > 0) {
1591 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1593 log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
1596 r = sd_bus_message_new_method_return(message, &reply);
1600 if (carries_install_info >= 0) {
1601 r = sd_bus_message_append(reply, "b", carries_install_info);
1606 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1610 for (i = 0; i < n_changes; i++) {
1611 r = sd_bus_message_append(
1613 unit_file_change_type_to_string(changes[i].type),
1620 r = sd_bus_message_close_container(reply);
1624 return sd_bus_send(bus, reply, NULL);
1627 unit_file_changes_free(changes, n_changes);
1631 static int method_enable_unit_files_generic(
1633 sd_bus_message *message,
1636 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1637 bool carries_install_info,
1638 sd_bus_error *error) {
1640 _cleanup_strv_free_ char **l = NULL;
1641 UnitFileChange *changes = NULL;
1642 unsigned n_changes = 0;
1643 UnitFileScope scope;
1644 int runtime, force, r;
1650 r = bus_verify_manage_unit_files_async(m, message, error);
1654 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1656 r = sd_bus_message_read_strv(message, &l);
1660 r = sd_bus_message_read(message, "bb", &runtime, &force);
1664 r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
1668 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1670 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1674 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1677 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1678 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1681 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1682 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1685 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1686 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1689 static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1690 return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1693 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1694 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
1697 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1698 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1701 static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1703 _cleanup_strv_free_ char **l = NULL;
1704 UnitFileChange *changes = NULL;
1705 unsigned n_changes = 0;
1706 Manager *m = userdata;
1707 UnitFilePresetMode mm;
1708 UnitFileScope scope;
1709 int runtime, force, r;
1716 r = bus_verify_manage_unit_files_async(m, message, error);
1720 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1722 r = sd_bus_message_read_strv(message, &l);
1726 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1731 mm = UNIT_FILE_PRESET_FULL;
1733 mm = unit_file_preset_mode_from_string(mode);
1738 r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1742 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1744 r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
1748 return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
1751 static int method_disable_unit_files_generic(
1753 sd_bus_message *message,
1756 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1757 sd_bus_error *error) {
1759 _cleanup_strv_free_ char **l = NULL;
1760 UnitFileChange *changes = NULL;
1761 unsigned n_changes = 0;
1762 UnitFileScope scope;
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 r = mac_selinux_access_check(message, verb, error);
1779 r = sd_bus_message_read_strv(message, &l);
1783 r = sd_bus_message_read(message, "b", &runtime);
1787 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1789 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1793 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1796 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1797 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1800 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1801 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1804 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1805 UnitFileChange *changes = NULL;
1806 unsigned n_changes = 0;
1807 Manager *m = userdata;
1808 UnitFileScope scope;
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 = mac_selinux_access_check(message, "enable", error);
1826 r = sd_bus_message_read(message, "sb", &name, &force);
1830 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1832 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1836 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1839 static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1840 UnitFileChange *changes = NULL;
1841 unsigned n_changes = 0;
1842 Manager *m = userdata;
1843 UnitFilePresetMode mm;
1844 UnitFileScope scope;
1846 int force, runtime, r;
1852 r = bus_verify_manage_unit_files_async(m, message, error);
1856 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1858 r = mac_selinux_access_check(message, "enable", error);
1862 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1867 mm = UNIT_FILE_PRESET_FULL;
1869 mm = unit_file_preset_mode_from_string(mode);
1874 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1876 r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
1880 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1883 static int method_add_dependency_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1884 _cleanup_strv_free_ char **l = NULL;
1885 Manager *m = userdata;
1886 UnitFileChange *changes = NULL;
1887 unsigned n_changes = 0;
1888 UnitFileScope scope;
1889 int runtime, force, r;
1898 r = bus_verify_manage_unit_files_async(m, message, error);
1902 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1904 r = sd_bus_message_read_strv(message, &l);
1908 r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
1912 dep = unit_dependency_from_string(type);
1916 r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1920 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1922 r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
1926 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1929 const sd_bus_vtable bus_manager_vtable[] = {
1930 SD_BUS_VTABLE_START(0),
1932 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1933 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1934 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1935 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1936 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1937 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1938 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1939 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1940 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1941 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1942 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1943 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1944 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1945 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1946 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1947 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1948 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1949 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1950 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1951 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1952 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, 0),
1953 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1954 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1955 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1956 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1957 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1958 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1959 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1960 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1961 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1962 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1963 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1964 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1965 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1966 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
1968 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1969 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1970 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1971 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1972 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
1973 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1974 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1975 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1976 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1977 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1978 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1979 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1980 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1981 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
1982 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1983 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1984 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
1985 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1986 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1987 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1988 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
1989 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1990 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1991 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1992 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1993 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1994 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1995 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
1996 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
1997 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1998 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1999 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2000 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2001 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2002 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2003 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
2004 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
2005 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
2006 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2007 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
2008 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2009 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2010 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2011 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2012 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2013 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2014 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2015 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2016 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2017 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2018 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2019 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2021 SD_BUS_SIGNAL("UnitNew", "so", 0),
2022 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2023 SD_BUS_SIGNAL("JobNew", "uos", 0),
2024 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2025 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2026 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2027 SD_BUS_SIGNAL("Reloading", "b", 0),
2032 static int send_finished(sd_bus *bus, void *userdata) {
2033 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2034 usec_t *times = userdata;
2040 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2044 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2048 return sd_bus_send(bus, message, NULL);
2051 void bus_manager_send_finished(
2053 usec_t firmware_usec,
2057 usec_t userspace_usec,
2058 usec_t total_usec) {
2064 r = bus_foreach_bus(
2077 log_debug_errno(r, "Failed to send finished signal: %m");
2080 static int send_reloading(sd_bus *bus, void *userdata) {
2081 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2086 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2090 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2094 return sd_bus_send(bus, message, NULL);
2097 void bus_manager_send_reloading(Manager *m, bool active) {
2102 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2104 log_debug_errno(r, "Failed to send reloading signal: %m");