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-client-track.h"
41 #include "dbus-execute.h"
42 #include "bus-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 (hwclock_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_jobs(
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) hashmap_size(m->jobs));
261 static int property_get_progress(
264 const char *interface,
265 const char *property,
266 sd_bus_message *reply,
268 sd_bus_error *error) {
270 Manager *m = userdata;
277 if (dual_timestamp_is_set(&m->finish_timestamp))
280 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
282 return sd_bus_message_append(reply, "d", d);
285 static int property_set_runtime_watchdog(
288 const char *interface,
289 const char *property,
290 sd_bus_message *value,
292 sd_bus_error *error) {
294 usec_t *t = userdata;
300 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
302 r = sd_bus_message_read(value, "t", t);
306 return watchdog_set_timeout(t);
309 static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
310 _cleanup_free_ char *path = NULL;
311 Manager *m = userdata;
320 r = sd_bus_message_read(message, "s", &name);
324 u = manager_get_unit(m, name);
326 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
328 r = selinux_unit_access_check(u, bus, message, "status", error);
332 path = unit_dbus_path(u);
336 return sd_bus_reply_method_return(message, "o", path);
339 static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
340 _cleanup_free_ char *path = NULL;
341 Manager *m = userdata;
350 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
352 r = sd_bus_message_read(message, "u", &pid);
357 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
359 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
363 r = sd_bus_creds_get_pid(creds, &pid);
368 u = manager_get_unit_by_pid(m, pid);
370 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
372 r = selinux_unit_access_check(u, bus, message, "status", error);
376 path = unit_dbus_path(u);
380 return sd_bus_reply_method_return(message, "o", path);
383 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
384 _cleanup_free_ char *path = NULL;
385 Manager *m = userdata;
394 r = sd_bus_message_read(message, "s", &name);
398 r = manager_load_unit(m, name, NULL, error, &u);
402 r = selinux_unit_access_check(u, bus, message, "status", error);
406 path = unit_dbus_path(u);
410 return sd_bus_reply_method_return(message, "o", path);
413 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) {
422 r = sd_bus_message_read(message, "s", &name);
426 r = manager_load_unit(m, name, NULL, error, &u);
430 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
433 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
434 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
437 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
438 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
441 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
442 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
445 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
446 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
449 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
450 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
453 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
454 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
457 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
458 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
461 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
462 Manager *m = userdata;
463 const char *old_name;
471 r = sd_bus_message_read(message, "s", &old_name);
475 u = manager_get_unit(m, old_name);
476 if (!u || !u->job || u->job->type != JOB_START)
477 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
479 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
482 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
483 Manager *m = userdata;
492 r = sd_bus_message_read(message, "s", &name);
496 u = manager_get_unit(m, name);
498 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
500 return bus_unit_method_kill(bus, message, u, error);
503 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
504 Manager *m = userdata;
513 r = sd_bus_message_read(message, "s", &name);
517 u = manager_get_unit(m, name);
519 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
521 return bus_unit_method_reset_failed(bus, message, u, error);
524 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
525 Manager *m = userdata;
534 r = sd_bus_message_read(message, "s", &name);
538 u = manager_get_unit(m, name);
540 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
542 return bus_unit_method_set_properties(bus, message, u, error);
545 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
546 const char *name, *smode;
547 Manager *m = userdata;
557 r = sd_bus_message_read(message, "ss", &name, &smode);
561 t = unit_name_to_type(name);
563 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
565 if (!unit_vtable[t]->can_transient)
566 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
568 mode = job_mode_from_string(smode);
570 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
572 r = selinux_access_check(bus, message, "start", error);
576 r = manager_load_unit(m, name, NULL, error, &u);
580 if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
581 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
583 /* OK, the unit failed to load and is unreferenced, now let's
584 * fill in the transient data instead */
585 r = unit_make_transient(u);
589 /* Set our properties */
590 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
594 /* And load this stub fully */
599 manager_dispatch_load_queue(m);
601 /* Finally, start it */
602 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
605 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
606 _cleanup_free_ char *path = NULL;
607 Manager *m = userdata;
616 r = sd_bus_message_read(message, "u", &id);
620 j = manager_get_job(m, id);
622 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
624 r = selinux_unit_access_check(j->unit, bus, message, "status", error);
628 path = job_dbus_path(j);
632 return sd_bus_reply_method_return(message, "o", path);
635 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
636 Manager *m = userdata;
645 r = sd_bus_message_read(message, "u", &id);
649 j = manager_get_job(m, id);
651 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
653 r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
657 job_finish_and_invalidate(j, JOB_CANCELED, true);
659 return sd_bus_reply_method_return(message, NULL);
662 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
663 Manager *m = userdata;
670 r = selinux_access_check(bus, message, "reboot", error);
674 manager_clear_jobs(m);
676 return sd_bus_reply_method_return(message, NULL);
679 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
680 Manager *m = userdata;
687 r = selinux_access_check(bus, message, "reload", error);
691 manager_reset_failed(m);
693 return sd_bus_reply_method_return(message, NULL);
696 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
697 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
698 Manager *m = userdata;
708 r = selinux_access_check(bus, message, "status", error);
712 r = sd_bus_message_new_method_return(message, &reply);
716 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
720 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
721 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
727 following = unit_following(u);
729 unit_path = unit_dbus_path(u);
734 job_path = job_dbus_path(u->job);
739 r = sd_bus_message_append(
740 reply, "(ssssssouso)",
743 unit_load_state_to_string(u->load_state),
744 unit_active_state_to_string(unit_active_state(u)),
745 unit_sub_state_to_string(u),
746 following ? following->id : "",
748 u->job ? u->job->id : 0,
749 u->job ? job_type_to_string(u->job->type) : "",
750 job_path ? job_path : "/");
755 r = sd_bus_message_close_container(reply);
759 return sd_bus_send(bus, reply, NULL);
762 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
763 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
764 Manager *m = userdata;
773 r = selinux_access_check(bus, message, "status", error);
777 r = sd_bus_message_new_method_return(message, &reply);
781 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
785 HASHMAP_FOREACH(j, m->jobs, i) {
786 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
788 job_path = job_dbus_path(j);
792 unit_path = unit_dbus_path(j->unit);
796 r = sd_bus_message_append(
800 job_type_to_string(j->type),
801 job_state_to_string(j->state),
808 r = sd_bus_message_close_container(reply);
812 return sd_bus_send(bus, reply, NULL);
815 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
816 Manager *m = userdata;
823 r = selinux_access_check(bus, message, "status", error);
827 r = bus_client_track(&m->subscribed, bus, sd_bus_message_get_sender(message));
831 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
833 return sd_bus_reply_method_return(message, NULL);
836 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
837 Manager *m = userdata;
844 r = selinux_access_check(bus, message, "status", error);
848 r = bus_client_untrack(m->subscribed, bus, sd_bus_message_get_sender(message));
852 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
854 return sd_bus_reply_method_return(message, NULL);
857 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
858 _cleanup_free_ char *dump = NULL;
859 _cleanup_fclose_ FILE *f = NULL;
860 Manager *m = userdata;
868 r = selinux_access_check(bus, message, "status", error);
872 f = open_memstream(&dump, &size);
876 manager_dump_units(m, f, NULL);
877 manager_dump_jobs(m, f, NULL);
884 return sd_bus_reply_method_return(message, "s", dump);
887 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
888 _cleanup_free_ char *path = NULL;
889 Manager *m = userdata;
899 r = selinux_access_check(bus, message, "start", error);
903 r = sd_bus_message_read(message, "sb", &name, &cleanup);
910 r = snapshot_create(m, name, cleanup, error, &s);
914 path = unit_dbus_path(UNIT(s));
918 return sd_bus_reply_method_return(message, "o", path);
921 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
922 Manager *m = userdata;
931 r = selinux_access_check(bus, message, "stop", error);
935 r = sd_bus_message_read(message, "s", &name);
939 u = manager_get_unit(m, name);
941 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
943 if (u->type != UNIT_SNAPSHOT)
944 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
946 return bus_snapshot_method_remove(bus, message, u, error);
949 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
950 Manager *m = userdata;
957 r = selinux_access_check(bus, message, "reload", error);
961 /* Instead of sending the reply back right away, we just
962 * remember that we need to and then send it after the reload
963 * is finished. That way the caller knows when the reload
966 assert(!m->queued_message);
967 r = sd_bus_message_new_method_return(message, &m->queued_message);
971 m->queued_message_bus = sd_bus_ref(bus);
972 m->exit_code = MANAGER_RELOAD;
977 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
978 Manager *m = userdata;
985 r = selinux_access_check(bus, message, "reload", error);
989 /* We don't send a reply back here, the client should
990 * just wait for us disconnecting. */
992 m->exit_code = MANAGER_REEXECUTE;
996 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
997 Manager *m = userdata;
1004 r = selinux_access_check(bus, message, "halt", error);
1008 if (m->running_as == SYSTEMD_SYSTEM)
1009 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1011 m->exit_code = MANAGER_EXIT;
1013 return sd_bus_reply_method_return(message, NULL);
1016 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1017 Manager *m = userdata;
1024 r = selinux_access_check(bus, message, "reboot", error);
1028 if (m->running_as != SYSTEMD_SYSTEM)
1029 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1031 m->exit_code = MANAGER_REBOOT;
1033 return sd_bus_reply_method_return(message, NULL);
1037 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1038 Manager *m = userdata;
1045 r = selinux_access_check(bus, message, "halt", error);
1049 if (m->running_as != SYSTEMD_SYSTEM)
1050 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1052 m->exit_code = MANAGER_POWEROFF;
1054 return sd_bus_reply_method_return(message, NULL);
1057 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1058 Manager *m = userdata;
1065 r = selinux_access_check(bus, message, "halt", error);
1069 if (m->running_as != SYSTEMD_SYSTEM)
1070 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1072 m->exit_code = MANAGER_HALT;
1074 return sd_bus_reply_method_return(message, NULL);
1077 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1078 Manager *m = userdata;
1085 r = selinux_access_check(bus, message, "reboot", error);
1089 if (m->running_as != SYSTEMD_SYSTEM)
1090 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1092 m->exit_code = MANAGER_KEXEC;
1094 return sd_bus_reply_method_return(message, NULL);
1097 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1098 char *ri = NULL, *rt = NULL;
1099 const char *root, *init;
1100 Manager *m = userdata;
1107 r = selinux_access_check(bus, message, "reboot", error);
1111 if (m->running_as != SYSTEMD_SYSTEM)
1112 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1114 r = sd_bus_message_read(message, "ss", &root, &init);
1118 if (path_equal(root, "/") || !path_is_absolute(root))
1119 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1122 if (isempty(init)) {
1123 if (! path_is_os_tree(root))
1124 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);
1126 _cleanup_free_ char *p = NULL;
1128 if (!path_is_absolute(init))
1129 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1131 p = strappend(root, init);
1135 if (access(p, X_OK) < 0)
1136 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1143 if (!isempty(init)) {
1151 free(m->switch_root);
1152 m->switch_root = rt;
1154 free(m->switch_root_init);
1155 m->switch_root_init = ri;
1157 m->exit_code = MANAGER_SWITCH_ROOT;
1159 return sd_bus_reply_method_return(message, NULL);
1162 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1163 _cleanup_strv_free_ char **plus = NULL;
1164 Manager *m = userdata;
1171 r = selinux_access_check(bus, message, "reload", error);
1175 r = sd_bus_message_read_strv(message, &plus);
1178 if (!strv_env_is_valid(plus))
1179 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1181 r = manager_environment_add(m, NULL, plus);
1185 return sd_bus_reply_method_return(message, NULL);
1188 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1189 _cleanup_strv_free_ char **minus = NULL;
1190 Manager *m = userdata;
1197 r = selinux_access_check(bus, message, "reload", error);
1201 r = sd_bus_message_read_strv(message, &minus);
1205 if (!strv_env_name_or_assignment_is_valid(minus))
1206 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1208 r = manager_environment_add(m, minus, NULL);
1212 return sd_bus_reply_method_return(message, NULL);
1215 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1216 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1217 Manager *m = userdata;
1224 r = selinux_access_check(bus, message, "reload", error);
1228 r = sd_bus_message_read_strv(message, &plus);
1232 r = sd_bus_message_read_strv(message, &minus);
1236 if (!strv_env_is_valid(plus))
1237 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1238 if (!strv_env_name_or_assignment_is_valid(minus))
1239 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1241 r = manager_environment_add(m, minus, plus);
1245 return sd_bus_reply_method_return(message, NULL);
1248 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1249 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1250 Manager *m = userdata;
1260 r = selinux_access_check(bus, message, "status", error);
1264 r = sd_bus_message_new_method_return(message, &reply);
1268 h = hashmap_new(string_hash_func, string_compare_func);
1272 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1276 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1280 HASHMAP_FOREACH(item, h, i) {
1282 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1287 unit_file_list_free(h);
1289 r = sd_bus_message_close_container(reply);
1293 return sd_bus_send(bus, reply, NULL);
1296 unit_file_list_free(h);
1300 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1301 Manager *m = userdata;
1303 UnitFileState state;
1304 UnitFileScope scope;
1311 r = selinux_access_check(bus, message, "status", error);
1315 r = sd_bus_message_read(message, "s", &name);
1319 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1321 state = unit_file_get_state(scope, NULL, name);
1325 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1328 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1329 _cleanup_free_ char *default_target = NULL;
1330 Manager *m = userdata;
1331 UnitFileScope scope;
1338 r = selinux_access_check(bus, message, "status", error);
1342 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1344 r = unit_file_get_default(scope, NULL, &default_target);
1348 return sd_bus_reply_method_return(message, "s", default_target);
1351 static int send_unit_files_changed(sd_bus *bus, const char *destination, void *userdata) {
1352 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1357 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1361 return sd_bus_send_to(bus, message, destination, NULL);
1364 static int reply_unit_file_changes_and_free(
1367 sd_bus_message *message,
1368 int carries_install_info,
1369 UnitFileChange *changes,
1370 unsigned n_changes) {
1372 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1377 bus_manager_foreach_client(m, send_unit_files_changed, NULL);
1379 r = sd_bus_message_new_method_return(message, &reply);
1383 if (carries_install_info >= 0) {
1384 r = sd_bus_message_append(reply, "b", carries_install_info);
1389 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1393 for (i = 0; i < n_changes; i++) {
1394 r = sd_bus_message_append(
1396 unit_file_change_type_to_string(changes[i].type),
1403 r = sd_bus_message_close_container(reply);
1407 return sd_bus_send(bus, reply, NULL);
1410 unit_file_changes_free(changes, n_changes);
1414 static int method_enable_unit_files_generic(
1416 sd_bus_message *message,
1419 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1420 bool carries_install_info,
1421 sd_bus_error *error) {
1423 _cleanup_strv_free_ char **l = NULL;
1427 UnitFileChange *changes = NULL;
1428 unsigned n_changes = 0;
1429 UnitFileScope scope;
1430 int runtime, force, r;
1436 r = sd_bus_message_read_strv(message, &l);
1441 STRV_FOREACH(i, l) {
1444 u = manager_get_unit(m, *i);
1446 r = selinux_unit_access_check(u, bus, message, verb, error);
1453 r = sd_bus_message_read(message, "bb", &runtime, &force);
1457 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1459 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1463 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1466 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1467 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1470 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1471 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1474 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1475 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1478 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1479 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
1482 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1483 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1486 static int method_disable_unit_files_generic(
1488 sd_bus_message *message,
1491 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1492 sd_bus_error *error) {
1494 _cleanup_strv_free_ char **l = NULL;
1495 UnitFileChange *changes = NULL;
1496 unsigned n_changes = 0;
1497 UnitFileScope scope;
1504 r = selinux_access_check(bus, message, verb, error);
1508 r = sd_bus_message_read_strv(message, &l);
1512 r = sd_bus_message_read(message, "b", &runtime);
1516 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1518 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1522 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1525 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1526 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1529 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1530 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1533 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1534 UnitFileChange *changes = NULL;
1535 unsigned n_changes = 0;
1536 Manager *m = userdata;
1537 UnitFileScope scope;
1545 r = selinux_access_check(bus, message, "enable", error);
1549 r = sd_bus_message_read(message, "sb", &name, &force);
1553 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1555 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1559 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1562 const sd_bus_vtable bus_manager_vtable[] = {
1563 SD_BUS_VTABLE_START(0),
1565 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1566 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1567 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1568 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1569 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1570 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1571 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1572 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1573 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1574 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1575 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1576 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1577 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1578 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1579 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1580 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1581 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1582 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1583 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1584 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1585 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1586 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1587 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1588 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1589 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1590 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1591 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1592 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1593 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1594 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1595 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1596 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1597 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1599 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1600 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1601 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1602 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
1603 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
1604 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
1605 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
1606 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
1607 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
1608 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
1609 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
1610 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1611 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
1612 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, 0),
1613 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
1614 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1615 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
1616 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1617 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1618 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1619 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1620 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1621 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1622 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1623 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1624 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1625 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
1626 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
1627 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1628 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1629 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1630 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1631 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1632 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1633 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
1634 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
1635 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
1636 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1637 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
1638 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
1639 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
1640 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
1641 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
1642 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
1643 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
1644 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
1645 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
1646 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
1648 SD_BUS_SIGNAL("UnitNew", "so", 0),
1649 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1650 SD_BUS_SIGNAL("JobNew", "uos", 0),
1651 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1652 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1653 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
1654 SD_BUS_SIGNAL("Reloading", "b", 0),
1659 int bus_manager_foreach_client(Manager *m, int (*send_message)(sd_bus *bus, const char *destination, void *userdata), void *userdata) {
1665 n = set_size(m->subscribed);
1669 BusTrackedClient *d;
1671 assert_se(d = set_first(m->subscribed));
1672 return send_message(d->bus, isempty(d->name) ? NULL : d->name, userdata);
1677 /* Send to everybody */
1678 SET_FOREACH(b, m->private_buses, i) {
1679 r = send_message(b, NULL, userdata);
1685 r = send_message(m->api_bus, NULL, userdata);
1693 static int send_finished(sd_bus *bus, const char *destination, void *userdata) {
1694 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1695 usec_t *times = userdata;
1701 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
1705 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
1709 return sd_bus_send_to(bus, message, destination, NULL);
1712 void bus_manager_send_finished(
1714 usec_t firmware_usec,
1718 usec_t userspace_usec,
1719 usec_t total_usec) {
1725 r = bus_manager_foreach_client(m, send_finished,
1726 (usec_t[6]) { firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec });
1728 log_debug("Failed to send finished signal: %s", strerror(-r));
1731 static int send_reloading(sd_bus *bus, const char *destination, void *userdata) {
1732 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1737 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
1741 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
1745 return sd_bus_send_to(bus, message, destination, NULL);
1748 void bus_manager_send_reloading(Manager *m, bool active) {
1753 r = bus_manager_foreach_client(m, send_reloading, INT_TO_PTR(active));
1755 log_debug("Failed to send reloading signal: %s", strerror(-r));