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"
32 #include "path-util.h"
34 #include "architecture.h"
37 #include "dbus-manager.h"
38 #include "dbus-unit.h"
39 #include "dbus-snapshot.h"
40 #include "dbus-execute.h"
41 #include "bus-errors.h"
43 static int property_get_version(
46 const char *interface,
48 sd_bus_message *reply,
50 sd_bus_error *error) {
55 return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
58 static int property_get_features(
61 const char *interface,
63 sd_bus_message *reply,
65 sd_bus_error *error) {
70 return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
73 static int property_get_virtualization(
76 const char *interface,
78 sd_bus_message *reply,
80 sd_bus_error *error) {
82 const char *id = NULL;
87 detect_virtualization(&id);
89 return sd_bus_message_append(reply, "s", id);
92 static int property_get_architecture(
95 const char *interface,
97 sd_bus_message *reply,
99 sd_bus_error *error) {
104 return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
107 static int property_get_tainted(
110 const char *interface,
111 const char *property,
112 sd_bus_message *reply,
114 sd_bus_error *error) {
116 char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
117 _cleanup_free_ char *p = NULL;
118 Manager *m = userdata;
125 e = stpcpy(e, "split-usr:");
127 if (readlink_malloc("/etc/mtab", &p) < 0)
128 e = stpcpy(e, "mtab-not-symlink:");
130 if (access("/proc/cgroups", F_OK) < 0)
131 e = stpcpy(e, "cgroups-missing:");
133 if (hwclock_is_localtime() > 0)
134 e = stpcpy(e, "local-hwclock:");
136 /* remove the last ':' */
140 return sd_bus_message_append(reply, "s", buf);
143 static int property_get_log_target(
146 const char *interface,
147 const char *property,
148 sd_bus_message *reply,
150 sd_bus_error *error) {
155 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
158 static int property_set_log_target(
161 const char *interface,
162 const char *property,
163 sd_bus_message *value,
165 sd_bus_error *error) {
173 r = sd_bus_message_read(value, "s", &t);
177 return log_set_target_from_string(t);
180 static int property_get_log_level(
183 const char *interface,
184 const char *property,
185 sd_bus_message *reply,
187 sd_bus_error *error) {
189 _cleanup_free_ char *t = NULL;
195 r = log_level_to_string_alloc(log_get_max_level(), &t);
199 return sd_bus_message_append(reply, "s", t);
202 static int property_set_log_level(
205 const char *interface,
206 const char *property,
207 sd_bus_message *value,
209 sd_bus_error *error) {
217 r = sd_bus_message_read(value, "s", &t);
221 return log_set_max_level_from_string(t);
224 static int property_get_n_names(
227 const char *interface,
228 const char *property,
229 sd_bus_message *reply,
231 sd_bus_error *error) {
233 Manager *m = userdata;
239 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
242 static int property_get_n_failed_units(
245 const char *interface,
246 const char *property,
247 sd_bus_message *reply,
249 sd_bus_error *error) {
251 Manager *m = userdata;
257 return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
260 static int property_get_n_jobs(
263 const char *interface,
264 const char *property,
265 sd_bus_message *reply,
267 sd_bus_error *error) {
269 Manager *m = userdata;
275 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
278 static int property_get_progress(
281 const char *interface,
282 const char *property,
283 sd_bus_message *reply,
285 sd_bus_error *error) {
287 Manager *m = userdata;
294 if (dual_timestamp_is_set(&m->finish_timestamp))
297 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
299 return sd_bus_message_append(reply, "d", d);
302 static int property_get_system_state(
305 const char *interface,
306 const char *property,
307 sd_bus_message *reply,
309 sd_bus_error *error) {
311 Manager *m = userdata;
317 return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
320 static int property_set_runtime_watchdog(
323 const char *interface,
324 const char *property,
325 sd_bus_message *value,
327 sd_bus_error *error) {
329 usec_t *t = userdata;
335 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
337 r = sd_bus_message_read(value, "t", t);
341 return watchdog_set_timeout(t);
344 static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
345 _cleanup_free_ char *path = NULL;
346 Manager *m = userdata;
355 r = sd_bus_message_read(message, "s", &name);
359 u = manager_get_unit(m, name);
361 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
363 r = selinux_unit_access_check(u, bus, message, "status", error);
367 path = unit_dbus_path(u);
371 return sd_bus_reply_method_return(message, "o", path);
374 static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
375 _cleanup_free_ char *path = NULL;
376 Manager *m = userdata;
385 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
387 r = sd_bus_message_read(message, "u", &pid);
392 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
394 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
398 r = sd_bus_creds_get_pid(creds, &pid);
403 u = manager_get_unit_by_pid(m, pid);
405 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
407 r = selinux_unit_access_check(u, bus, message, "status", error);
411 path = unit_dbus_path(u);
415 return sd_bus_reply_method_return(message, "o", path);
418 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
419 _cleanup_free_ char *path = NULL;
420 Manager *m = userdata;
429 r = sd_bus_message_read(message, "s", &name);
433 r = manager_load_unit(m, name, NULL, error, &u);
437 r = selinux_unit_access_check(u, bus, message, "status", error);
441 path = unit_dbus_path(u);
445 return sd_bus_reply_method_return(message, "o", path);
448 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) {
457 r = sd_bus_message_read(message, "s", &name);
461 r = manager_load_unit(m, name, NULL, error, &u);
465 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
468 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
469 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
472 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
473 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
476 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
477 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
480 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
481 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
484 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
485 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
488 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
489 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
492 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
493 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
496 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
497 Manager *m = userdata;
498 const char *old_name;
506 r = sd_bus_message_read(message, "s", &old_name);
510 u = manager_get_unit(m, old_name);
511 if (!u || !u->job || u->job->type != JOB_START)
512 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
514 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
517 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
518 Manager *m = userdata;
527 r = sd_bus_message_read(message, "s", &name);
531 u = manager_get_unit(m, name);
533 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
535 return bus_unit_method_kill(bus, message, u, error);
538 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
539 Manager *m = userdata;
548 r = sd_bus_message_read(message, "s", &name);
552 u = manager_get_unit(m, name);
554 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
556 return bus_unit_method_reset_failed(bus, message, u, error);
559 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
560 Manager *m = userdata;
569 r = sd_bus_message_read(message, "s", &name);
573 u = manager_get_unit(m, name);
575 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
577 return bus_unit_method_set_properties(bus, message, u, error);
580 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
581 const char *name, *smode;
582 Manager *m = userdata;
592 r = sd_bus_message_read(message, "ss", &name, &smode);
596 t = unit_name_to_type(name);
598 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
600 if (!unit_vtable[t]->can_transient)
601 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
603 mode = job_mode_from_string(smode);
605 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
607 r = selinux_access_check(bus, message, "start", error);
611 r = manager_load_unit(m, name, NULL, error, &u);
615 if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
616 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
618 /* OK, the unit failed to load and is unreferenced, now let's
619 * fill in the transient data instead */
620 r = unit_make_transient(u);
624 /* Set our properties */
625 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
629 /* And load this stub fully */
634 manager_dispatch_load_queue(m);
636 /* Finally, start it */
637 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
640 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
641 _cleanup_free_ char *path = NULL;
642 Manager *m = userdata;
651 r = sd_bus_message_read(message, "u", &id);
655 j = manager_get_job(m, id);
657 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
659 r = selinux_unit_access_check(j->unit, bus, message, "status", error);
663 path = job_dbus_path(j);
667 return sd_bus_reply_method_return(message, "o", path);
670 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
671 Manager *m = userdata;
680 r = sd_bus_message_read(message, "u", &id);
684 j = manager_get_job(m, id);
686 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
688 r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
692 job_finish_and_invalidate(j, JOB_CANCELED, true);
694 return sd_bus_reply_method_return(message, NULL);
697 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
698 Manager *m = userdata;
705 r = selinux_access_check(bus, message, "reboot", error);
709 manager_clear_jobs(m);
711 return sd_bus_reply_method_return(message, NULL);
714 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
715 Manager *m = userdata;
722 r = selinux_access_check(bus, message, "reload", error);
726 manager_reset_failed(m);
728 return sd_bus_reply_method_return(message, NULL);
731 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
732 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
733 Manager *m = userdata;
743 r = selinux_access_check(bus, message, "status", error);
747 r = sd_bus_message_new_method_return(message, &reply);
751 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
755 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
756 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
762 following = unit_following(u);
764 unit_path = unit_dbus_path(u);
769 job_path = job_dbus_path(u->job);
774 r = sd_bus_message_append(
775 reply, "(ssssssouso)",
778 unit_load_state_to_string(u->load_state),
779 unit_active_state_to_string(unit_active_state(u)),
780 unit_sub_state_to_string(u),
781 following ? following->id : "",
783 u->job ? u->job->id : 0,
784 u->job ? job_type_to_string(u->job->type) : "",
785 job_path ? job_path : "/");
790 r = sd_bus_message_close_container(reply);
794 return sd_bus_send(bus, reply, NULL);
797 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
798 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
799 Manager *m = userdata;
808 r = selinux_access_check(bus, message, "status", error);
812 r = sd_bus_message_new_method_return(message, &reply);
816 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
820 HASHMAP_FOREACH(j, m->jobs, i) {
821 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
823 job_path = job_dbus_path(j);
827 unit_path = unit_dbus_path(j->unit);
831 r = sd_bus_message_append(
835 job_type_to_string(j->type),
836 job_state_to_string(j->state),
843 r = sd_bus_message_close_container(reply);
847 return sd_bus_send(bus, reply, NULL);
850 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
851 Manager *m = userdata;
858 r = selinux_access_check(bus, message, "status", error);
862 if (bus == m->api_bus) {
864 /* Note that direct bus connection subscribe by
865 * default, we only track peers on the API bus here */
867 if (!m->subscribed) {
868 r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
873 r = sd_bus_track_add_sender(m->subscribed, message);
877 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
880 return sd_bus_reply_method_return(message, NULL);
883 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
884 Manager *m = userdata;
891 r = selinux_access_check(bus, message, "status", error);
895 if (bus == m->api_bus) {
896 r = sd_bus_track_remove_sender(m->subscribed, message);
900 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
903 return sd_bus_reply_method_return(message, NULL);
906 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
907 _cleanup_free_ char *dump = NULL;
908 _cleanup_fclose_ FILE *f = NULL;
909 Manager *m = userdata;
917 r = selinux_access_check(bus, message, "status", error);
921 f = open_memstream(&dump, &size);
925 manager_dump_units(m, f, NULL);
926 manager_dump_jobs(m, f, NULL);
933 return sd_bus_reply_method_return(message, "s", dump);
936 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
937 _cleanup_free_ char *path = NULL;
938 Manager *m = userdata;
948 r = selinux_access_check(bus, message, "start", error);
952 r = sd_bus_message_read(message, "sb", &name, &cleanup);
959 r = snapshot_create(m, name, cleanup, error, &s);
963 path = unit_dbus_path(UNIT(s));
967 return sd_bus_reply_method_return(message, "o", path);
970 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
971 Manager *m = userdata;
980 r = selinux_access_check(bus, message, "stop", error);
984 r = sd_bus_message_read(message, "s", &name);
988 u = manager_get_unit(m, name);
990 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
992 if (u->type != UNIT_SNAPSHOT)
993 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
995 return bus_snapshot_method_remove(bus, message, u, error);
998 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
999 Manager *m = userdata;
1006 r = selinux_access_check(bus, message, "reload", error);
1010 /* Instead of sending the reply back right away, we just
1011 * remember that we need to and then send it after the reload
1012 * is finished. That way the caller knows when the reload
1015 assert(!m->queued_message);
1016 r = sd_bus_message_new_method_return(message, &m->queued_message);
1020 m->queued_message_bus = sd_bus_ref(bus);
1021 m->exit_code = MANAGER_RELOAD;
1026 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1027 Manager *m = userdata;
1034 r = selinux_access_check(bus, message, "reload", error);
1038 /* We don't send a reply back here, the client should
1039 * just wait for us disconnecting. */
1041 m->exit_code = MANAGER_REEXECUTE;
1045 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1046 Manager *m = userdata;
1053 r = selinux_access_check(bus, message, "halt", error);
1057 if (m->running_as == SYSTEMD_SYSTEM)
1058 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1060 m->exit_code = MANAGER_EXIT;
1062 return sd_bus_reply_method_return(message, NULL);
1065 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1066 Manager *m = userdata;
1073 r = selinux_access_check(bus, message, "reboot", error);
1077 if (m->running_as != SYSTEMD_SYSTEM)
1078 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1080 m->exit_code = MANAGER_REBOOT;
1082 return sd_bus_reply_method_return(message, NULL);
1086 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1087 Manager *m = userdata;
1094 r = selinux_access_check(bus, message, "halt", error);
1098 if (m->running_as != SYSTEMD_SYSTEM)
1099 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1101 m->exit_code = MANAGER_POWEROFF;
1103 return sd_bus_reply_method_return(message, NULL);
1106 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1107 Manager *m = userdata;
1114 r = selinux_access_check(bus, message, "halt", error);
1118 if (m->running_as != SYSTEMD_SYSTEM)
1119 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1121 m->exit_code = MANAGER_HALT;
1123 return sd_bus_reply_method_return(message, NULL);
1126 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1127 Manager *m = userdata;
1134 r = selinux_access_check(bus, message, "reboot", error);
1138 if (m->running_as != SYSTEMD_SYSTEM)
1139 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1141 m->exit_code = MANAGER_KEXEC;
1143 return sd_bus_reply_method_return(message, NULL);
1146 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1147 char *ri = NULL, *rt = NULL;
1148 const char *root, *init;
1149 Manager *m = userdata;
1156 r = selinux_access_check(bus, message, "reboot", error);
1160 if (m->running_as != SYSTEMD_SYSTEM)
1161 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1163 r = sd_bus_message_read(message, "ss", &root, &init);
1167 if (path_equal(root, "/") || !path_is_absolute(root))
1168 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1171 if (isempty(init)) {
1172 if (! path_is_os_tree(root))
1173 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root);
1175 _cleanup_free_ char *p = NULL;
1177 if (!path_is_absolute(init))
1178 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1180 p = strappend(root, init);
1184 if (access(p, X_OK) < 0)
1185 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1192 if (!isempty(init)) {
1200 free(m->switch_root);
1201 m->switch_root = rt;
1203 free(m->switch_root_init);
1204 m->switch_root_init = ri;
1206 m->exit_code = MANAGER_SWITCH_ROOT;
1208 return sd_bus_reply_method_return(message, NULL);
1211 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1212 _cleanup_strv_free_ char **plus = NULL;
1213 Manager *m = userdata;
1220 r = selinux_access_check(bus, message, "reload", error);
1224 r = sd_bus_message_read_strv(message, &plus);
1227 if (!strv_env_is_valid(plus))
1228 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1230 r = manager_environment_add(m, NULL, plus);
1234 return sd_bus_reply_method_return(message, NULL);
1237 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1238 _cleanup_strv_free_ char **minus = NULL;
1239 Manager *m = userdata;
1246 r = selinux_access_check(bus, message, "reload", error);
1250 r = sd_bus_message_read_strv(message, &minus);
1254 if (!strv_env_name_or_assignment_is_valid(minus))
1255 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1257 r = manager_environment_add(m, minus, NULL);
1261 return sd_bus_reply_method_return(message, NULL);
1264 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1265 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1266 Manager *m = userdata;
1273 r = selinux_access_check(bus, message, "reload", error);
1277 r = sd_bus_message_read_strv(message, &plus);
1281 r = sd_bus_message_read_strv(message, &minus);
1285 if (!strv_env_is_valid(plus))
1286 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1287 if (!strv_env_name_or_assignment_is_valid(minus))
1288 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1290 r = manager_environment_add(m, minus, plus);
1294 return sd_bus_reply_method_return(message, NULL);
1297 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1298 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1299 Manager *m = userdata;
1309 r = selinux_access_check(bus, message, "status", error);
1313 r = sd_bus_message_new_method_return(message, &reply);
1317 h = hashmap_new(string_hash_func, string_compare_func);
1321 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1325 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1329 HASHMAP_FOREACH(item, h, i) {
1331 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1336 unit_file_list_free(h);
1338 r = sd_bus_message_close_container(reply);
1342 return sd_bus_send(bus, reply, NULL);
1345 unit_file_list_free(h);
1349 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1350 Manager *m = userdata;
1352 UnitFileState state;
1353 UnitFileScope scope;
1360 r = selinux_access_check(bus, message, "status", error);
1364 r = sd_bus_message_read(message, "s", &name);
1368 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1370 state = unit_file_get_state(scope, NULL, name);
1374 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1377 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1378 _cleanup_free_ char *default_target = NULL;
1379 Manager *m = userdata;
1380 UnitFileScope scope;
1387 r = selinux_access_check(bus, message, "status", error);
1391 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1393 r = unit_file_get_default(scope, NULL, &default_target);
1397 return sd_bus_reply_method_return(message, "s", default_target);
1400 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1401 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1406 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1410 return sd_bus_send(bus, message, NULL);
1413 static int reply_unit_file_changes_and_free(
1416 sd_bus_message *message,
1417 int carries_install_info,
1418 UnitFileChange *changes,
1419 unsigned n_changes) {
1421 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1425 if (n_changes > 0) {
1426 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1428 log_debug("Failed to send UnitFilesChanged signal: %s", strerror(-r));
1431 r = sd_bus_message_new_method_return(message, &reply);
1435 if (carries_install_info >= 0) {
1436 r = sd_bus_message_append(reply, "b", carries_install_info);
1441 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1445 for (i = 0; i < n_changes; i++) {
1446 r = sd_bus_message_append(
1448 unit_file_change_type_to_string(changes[i].type),
1455 r = sd_bus_message_close_container(reply);
1459 return sd_bus_send(bus, reply, NULL);
1462 unit_file_changes_free(changes, n_changes);
1466 static int method_enable_unit_files_generic(
1468 sd_bus_message *message,
1471 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1472 bool carries_install_info,
1473 sd_bus_error *error) {
1475 _cleanup_strv_free_ char **l = NULL;
1479 UnitFileChange *changes = NULL;
1480 unsigned n_changes = 0;
1481 UnitFileScope scope;
1482 int runtime, force, r;
1488 r = sd_bus_message_read_strv(message, &l);
1493 STRV_FOREACH(i, l) {
1496 u = manager_get_unit(m, *i);
1498 r = selinux_unit_access_check(u, bus, message, verb, error);
1505 r = sd_bus_message_read(message, "bb", &runtime, &force);
1509 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1511 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1515 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1518 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1519 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1522 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1523 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1526 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1527 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1530 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1531 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
1534 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1535 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1538 static int method_disable_unit_files_generic(
1540 sd_bus_message *message,
1543 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1544 sd_bus_error *error) {
1546 _cleanup_strv_free_ char **l = NULL;
1547 UnitFileChange *changes = NULL;
1548 unsigned n_changes = 0;
1549 UnitFileScope scope;
1556 r = selinux_access_check(bus, message, verb, error);
1560 r = sd_bus_message_read_strv(message, &l);
1564 r = sd_bus_message_read(message, "b", &runtime);
1568 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1570 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1574 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1577 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1578 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1581 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1582 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1585 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1586 UnitFileChange *changes = NULL;
1587 unsigned n_changes = 0;
1588 Manager *m = userdata;
1589 UnitFileScope scope;
1597 r = selinux_access_check(bus, message, "enable", error);
1601 r = sd_bus_message_read(message, "sb", &name, &force);
1605 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1607 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1611 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1614 const sd_bus_vtable bus_manager_vtable[] = {
1615 SD_BUS_VTABLE_START(0),
1617 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1618 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1619 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1620 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1621 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1622 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1623 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1624 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1625 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1626 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1627 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1628 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1629 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1630 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1631 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1632 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1633 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1634 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1635 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1636 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1637 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, 0),
1638 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1639 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1640 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1641 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1642 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1643 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1644 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1645 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1646 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1647 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1648 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1649 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1650 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1651 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
1653 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1654 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1655 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1656 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
1657 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
1658 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
1659 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
1660 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
1661 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
1662 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
1663 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
1664 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1665 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
1666 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, 0),
1667 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
1668 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1669 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
1670 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1671 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1672 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1673 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1674 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1675 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1676 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1677 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1678 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1679 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
1680 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
1681 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1682 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1683 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1684 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1685 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1686 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1687 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
1688 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
1689 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
1690 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1691 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
1692 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
1693 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
1694 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
1695 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
1696 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
1697 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
1698 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
1699 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
1700 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
1702 SD_BUS_SIGNAL("UnitNew", "so", 0),
1703 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1704 SD_BUS_SIGNAL("JobNew", "uos", 0),
1705 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1706 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1707 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
1708 SD_BUS_SIGNAL("Reloading", "b", 0),
1713 static int send_finished(sd_bus *bus, void *userdata) {
1714 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1715 usec_t *times = userdata;
1721 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
1725 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
1729 return sd_bus_send(bus, message, NULL);
1732 void bus_manager_send_finished(
1734 usec_t firmware_usec,
1738 usec_t userspace_usec,
1739 usec_t total_usec) {
1745 r = bus_foreach_bus(
1758 log_debug("Failed to send finished signal: %s", strerror(-r));
1761 static int send_reloading(sd_bus *bus, void *userdata) {
1762 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1767 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
1771 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
1775 return sd_bus_send(bus, message, NULL);
1778 void bus_manager_send_reloading(Manager *m, bool active) {
1783 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
1785 log_debug("Failed to send reloading signal: %s", strerror(-r));