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"
36 #include "dbus-manager.h"
37 #include "dbus-unit.h"
38 #include "dbus-snapshot.h"
39 #include "dbus-client-track.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_tainted(
95 const char *interface,
97 sd_bus_message *reply,
99 sd_bus_error *error) {
101 char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
102 _cleanup_free_ char *p = NULL;
103 Manager *m = userdata;
110 e = stpcpy(e, "split-usr:");
112 if (readlink_malloc("/etc/mtab", &p) < 0)
113 e = stpcpy(e, "mtab-not-symlink:");
115 if (access("/proc/cgroups", F_OK) < 0)
116 e = stpcpy(e, "cgroups-missing:");
118 if (hwclock_is_localtime() > 0)
119 e = stpcpy(e, "local-hwclock:");
121 /* remove the last ':' */
125 return sd_bus_message_append(reply, "s", buf);
128 static int property_get_log_target(
131 const char *interface,
132 const char *property,
133 sd_bus_message *reply,
135 sd_bus_error *error) {
140 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
143 static int property_set_log_target(
146 const char *interface,
147 const char *property,
148 sd_bus_message *value,
150 sd_bus_error *error) {
158 r = sd_bus_message_read(value, "s", &t);
162 return log_set_target_from_string(t);
165 static int property_get_log_level(
168 const char *interface,
169 const char *property,
170 sd_bus_message *reply,
172 sd_bus_error *error) {
174 _cleanup_free_ char *t = NULL;
180 r = log_level_to_string_alloc(log_get_max_level(), &t);
184 return sd_bus_message_append(reply, "s", t);
187 static int property_set_log_level(
190 const char *interface,
191 const char *property,
192 sd_bus_message *value,
194 sd_bus_error *error) {
202 r = sd_bus_message_read(value, "s", &t);
206 return log_set_max_level_from_string(t);
209 static int property_get_n_names(
212 const char *interface,
213 const char *property,
214 sd_bus_message *reply,
216 sd_bus_error *error) {
218 Manager *m = userdata;
224 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
227 static int property_get_n_jobs(
230 const char *interface,
231 const char *property,
232 sd_bus_message *reply,
234 sd_bus_error *error) {
236 Manager *m = userdata;
242 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
245 static int property_get_progress(
248 const char *interface,
249 const char *property,
250 sd_bus_message *reply,
252 sd_bus_error *error) {
254 Manager *m = userdata;
261 if (dual_timestamp_is_set(&m->finish_timestamp))
264 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
266 return sd_bus_message_append(reply, "d", d);
269 static int property_set_runtime_watchdog(
272 const char *interface,
273 const char *property,
274 sd_bus_message *value,
276 sd_bus_error *error) {
278 usec_t *t = userdata;
284 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
286 r = sd_bus_message_read(value, "t", t);
290 return watchdog_set_timeout(t);
293 static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
294 _cleanup_free_ char *path = NULL;
295 Manager *m = userdata;
304 r = sd_bus_message_read(message, "s", &name);
308 u = manager_get_unit(m, name);
310 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
312 r = selinux_unit_access_check(u, bus, message, "status", error);
316 path = unit_dbus_path(u);
320 return sd_bus_reply_method_return(message, "o", path);
323 static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
324 _cleanup_free_ char *path = NULL;
325 Manager *m = userdata;
334 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
336 r = sd_bus_message_read(message, "u", &pid);
341 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
343 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
347 r = sd_bus_creds_get_pid(creds, &pid);
352 u = manager_get_unit_by_pid(m, pid);
354 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
356 r = selinux_unit_access_check(u, bus, message, "status", error);
360 path = unit_dbus_path(u);
364 return sd_bus_reply_method_return(message, "o", path);
367 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
368 _cleanup_free_ char *path = NULL;
369 Manager *m = userdata;
378 r = sd_bus_message_read(message, "s", &name);
382 r = manager_load_unit(m, name, NULL, error, &u);
386 r = selinux_unit_access_check(u, bus, message, "status", error);
390 path = unit_dbus_path(u);
394 return sd_bus_reply_method_return(message, "o", path);
397 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) {
406 r = sd_bus_message_read(message, "s", &name);
410 r = manager_load_unit(m, name, NULL, error, &u);
414 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
417 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
418 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
421 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
422 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
425 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
426 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
429 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
430 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
433 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
434 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
437 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
438 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
441 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
442 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
445 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
446 Manager *m = userdata;
447 const char *old_name;
455 r = sd_bus_message_read(message, "s", &old_name);
459 u = manager_get_unit(m, old_name);
460 if (!u || !u->job || u->job->type != JOB_START)
461 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
463 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
466 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
467 Manager *m = userdata;
476 r = sd_bus_message_read(message, "s", &name);
480 u = manager_get_unit(m, name);
482 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
484 return bus_unit_method_kill(bus, message, u, error);
487 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
488 Manager *m = userdata;
497 r = sd_bus_message_read(message, "s", &name);
501 u = manager_get_unit(m, name);
503 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
505 return bus_unit_method_reset_failed(bus, message, u, error);
508 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
509 Manager *m = userdata;
518 r = sd_bus_message_read(message, "s", &name);
522 u = manager_get_unit(m, name);
524 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
526 return bus_unit_method_set_properties(bus, message, u, error);
529 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
530 const char *name, *smode;
531 Manager *m = userdata;
541 r = sd_bus_message_read(message, "ss", &name, &smode);
545 t = unit_name_to_type(name);
547 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
549 if (!unit_vtable[t]->can_transient)
550 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.");
552 mode = job_mode_from_string(smode);
554 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
556 r = selinux_access_check(bus, message, "start", error);
560 r = manager_load_unit(m, name, NULL, error, &u);
564 if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
565 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
567 /* OK, the unit failed to load and is unreferenced, now let's
568 * fill in the transient data instead */
569 r = unit_make_transient(u);
573 /* Set our properties */
574 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
578 /* And load this stub fully */
583 manager_dispatch_load_queue(m);
585 /* Finally, start it */
586 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
589 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
590 _cleanup_free_ char *path = NULL;
591 Manager *m = userdata;
600 r = sd_bus_message_read(message, "u", &id);
604 j = manager_get_job(m, id);
606 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
608 r = selinux_unit_access_check(j->unit, bus, message, "status", error);
612 path = job_dbus_path(j);
616 return sd_bus_reply_method_return(message, "o", path);
619 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
620 Manager *m = userdata;
629 r = sd_bus_message_read(message, "u", &id);
633 j = manager_get_job(m, id);
635 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
637 r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
641 job_finish_and_invalidate(j, JOB_CANCELED, true);
643 return sd_bus_reply_method_return(message, NULL);
646 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
647 Manager *m = userdata;
654 r = selinux_access_check(bus, message, "reboot", error);
658 manager_clear_jobs(m);
660 return sd_bus_reply_method_return(message, NULL);
663 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
664 Manager *m = userdata;
671 r = selinux_access_check(bus, message, "reload", error);
675 manager_reset_failed(m);
677 return sd_bus_reply_method_return(message, NULL);
680 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
681 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
682 Manager *m = userdata;
692 r = selinux_access_check(bus, message, "status", error);
696 r = sd_bus_message_new_method_return(message, &reply);
700 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
704 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
705 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
711 following = unit_following(u);
713 unit_path = unit_dbus_path(u);
718 job_path = job_dbus_path(u->job);
723 r = sd_bus_message_append(
724 reply, "(ssssssouso)",
727 unit_load_state_to_string(u->load_state),
728 unit_active_state_to_string(unit_active_state(u)),
729 unit_sub_state_to_string(u),
730 following ? following->id : "",
732 u->job ? u->job->id : 0,
733 u->job ? job_type_to_string(u->job->type) : "",
734 job_path ? job_path : "/");
739 r = sd_bus_message_close_container(reply);
743 return sd_bus_send(bus, reply, NULL);
746 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
747 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
748 Manager *m = userdata;
757 r = selinux_access_check(bus, message, "status", error);
761 r = sd_bus_message_new_method_return(message, &reply);
765 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
769 HASHMAP_FOREACH(j, m->jobs, i) {
770 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
772 job_path = job_dbus_path(j);
776 unit_path = unit_dbus_path(j->unit);
780 r = sd_bus_message_append(
784 job_type_to_string(j->type),
785 job_state_to_string(j->state),
792 r = sd_bus_message_close_container(reply);
796 return sd_bus_send(bus, reply, NULL);
799 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
800 Manager *m = userdata;
807 r = selinux_access_check(bus, message, "status", error);
811 r = bus_client_track(&m->subscribed, bus, sd_bus_message_get_sender(message));
815 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
817 return sd_bus_reply_method_return(message, NULL);
820 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
821 Manager *m = userdata;
828 r = selinux_access_check(bus, message, "status", error);
832 r = bus_client_untrack(m->subscribed, bus, sd_bus_message_get_sender(message));
836 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
838 return sd_bus_reply_method_return(message, NULL);
841 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
842 _cleanup_free_ char *dump = NULL;
843 _cleanup_fclose_ FILE *f = NULL;
844 Manager *m = userdata;
852 r = selinux_access_check(bus, message, "status", error);
856 f = open_memstream(&dump, &size);
860 manager_dump_units(m, f, NULL);
861 manager_dump_jobs(m, f, NULL);
868 return sd_bus_reply_method_return(message, "s", dump);
871 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
872 _cleanup_free_ char *path = NULL;
873 Manager *m = userdata;
883 r = selinux_access_check(bus, message, "start", error);
887 r = sd_bus_message_read(message, "sb", &name, &cleanup);
894 r = snapshot_create(m, name, cleanup, error, &s);
898 path = unit_dbus_path(UNIT(s));
902 return sd_bus_reply_method_return(message, "o", path);
905 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
906 Manager *m = userdata;
915 r = selinux_access_check(bus, message, "stop", error);
919 r = sd_bus_message_read(message, "s", &name);
923 u = manager_get_unit(m, name);
925 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
927 if (u->type != UNIT_SNAPSHOT)
928 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
930 return bus_snapshot_method_remove(bus, message, u, error);
933 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
934 Manager *m = userdata;
941 r = selinux_access_check(bus, message, "reload", error);
945 /* Instead of sending the reply back right away, we just
946 * remember that we need to and then send it after the reload
947 * is finished. That way the caller knows when the reload
950 assert(!m->queued_message);
951 r = sd_bus_message_new_method_return(message, &m->queued_message);
955 m->queued_message_bus = sd_bus_ref(bus);
956 m->exit_code = MANAGER_RELOAD;
961 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
962 Manager *m = userdata;
969 r = selinux_access_check(bus, message, "reload", error);
973 /* We don't send a reply back here, the client should
974 * just wait for us disconnecting. */
976 m->exit_code = MANAGER_REEXECUTE;
980 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
981 Manager *m = userdata;
988 r = selinux_access_check(bus, message, "halt", error);
992 if (m->running_as == SYSTEMD_SYSTEM)
993 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
995 m->exit_code = MANAGER_EXIT;
997 return sd_bus_reply_method_return(message, NULL);
1000 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1001 Manager *m = userdata;
1008 r = selinux_access_check(bus, message, "reboot", error);
1012 if (m->running_as != SYSTEMD_SYSTEM)
1013 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1015 m->exit_code = MANAGER_REBOOT;
1017 return sd_bus_reply_method_return(message, NULL);
1021 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1022 Manager *m = userdata;
1029 r = selinux_access_check(bus, message, "halt", error);
1033 if (m->running_as != SYSTEMD_SYSTEM)
1034 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1036 m->exit_code = MANAGER_POWEROFF;
1038 return sd_bus_reply_method_return(message, NULL);
1041 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1042 Manager *m = userdata;
1049 r = selinux_access_check(bus, message, "halt", error);
1053 if (m->running_as != SYSTEMD_SYSTEM)
1054 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1056 m->exit_code = MANAGER_HALT;
1058 return sd_bus_reply_method_return(message, NULL);
1061 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1062 Manager *m = userdata;
1069 r = selinux_access_check(bus, message, "reboot", error);
1073 if (m->running_as != SYSTEMD_SYSTEM)
1074 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1076 m->exit_code = MANAGER_KEXEC;
1078 return sd_bus_reply_method_return(message, NULL);
1081 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1082 char *ri = NULL, *rt = NULL;
1083 const char *root, *init;
1084 Manager *m = userdata;
1091 r = selinux_access_check(bus, message, "reboot", error);
1095 if (m->running_as != SYSTEMD_SYSTEM)
1096 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1098 r = sd_bus_message_read(message, "ss", &root, &init);
1102 if (path_equal(root, "/") || !path_is_absolute(root))
1103 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1106 if (isempty(init)) {
1107 if (! path_is_os_tree(root))
1108 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);
1110 _cleanup_free_ char *p = NULL;
1112 if (!path_is_absolute(init))
1113 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1115 p = strappend(root, init);
1119 if (access(p, X_OK) < 0)
1120 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1127 if (!isempty(init)) {
1135 free(m->switch_root);
1136 m->switch_root = rt;
1138 free(m->switch_root_init);
1139 m->switch_root_init = ri;
1141 m->exit_code = MANAGER_SWITCH_ROOT;
1143 return sd_bus_reply_method_return(message, NULL);
1146 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1147 _cleanup_strv_free_ char **plus = NULL;
1148 Manager *m = userdata;
1155 r = selinux_access_check(bus, message, "reload", error);
1159 r = sd_bus_message_read_strv(message, &plus);
1162 if (!strv_env_is_valid(plus))
1163 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1165 r = manager_environment_add(m, NULL, plus);
1169 return sd_bus_reply_method_return(message, NULL);
1172 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1173 _cleanup_strv_free_ char **minus = NULL;
1174 Manager *m = userdata;
1181 r = selinux_access_check(bus, message, "reload", error);
1185 r = sd_bus_message_read_strv(message, &minus);
1189 if (!strv_env_name_or_assignment_is_valid(minus))
1190 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1192 r = manager_environment_add(m, minus, NULL);
1196 return sd_bus_reply_method_return(message, NULL);
1199 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1200 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1201 Manager *m = userdata;
1208 r = selinux_access_check(bus, message, "reload", error);
1212 r = sd_bus_message_read_strv(message, &plus);
1216 r = sd_bus_message_read_strv(message, &minus);
1220 if (!strv_env_is_valid(plus))
1221 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1222 if (!strv_env_name_or_assignment_is_valid(minus))
1223 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1225 r = manager_environment_add(m, minus, plus);
1229 return sd_bus_reply_method_return(message, NULL);
1232 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1233 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1234 Manager *m = userdata;
1244 r = selinux_access_check(bus, message, "status", error);
1248 r = sd_bus_message_new_method_return(message, &reply);
1252 h = hashmap_new(string_hash_func, string_compare_func);
1256 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1260 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1264 HASHMAP_FOREACH(item, h, i) {
1266 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1271 unit_file_list_free(h);
1273 r = sd_bus_message_close_container(reply);
1277 return sd_bus_send(bus, reply, NULL);
1280 unit_file_list_free(h);
1284 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1285 Manager *m = userdata;
1287 UnitFileState state;
1288 UnitFileScope scope;
1295 r = selinux_access_check(bus, message, "status", error);
1299 r = sd_bus_message_read(message, "s", &name);
1303 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1305 state = unit_file_get_state(scope, NULL, name);
1309 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1312 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1313 _cleanup_free_ char *default_target = NULL;
1314 Manager *m = userdata;
1315 UnitFileScope scope;
1322 r = selinux_access_check(bus, message, "status", error);
1326 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1328 r = unit_file_get_default(scope, NULL, &default_target);
1332 return sd_bus_reply_method_return(message, "s", default_target);
1335 static int send_unit_files_changed(sd_bus *bus, const char *destination, void *userdata) {
1336 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1341 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged", &message);
1345 return sd_bus_send_to(bus, message, destination, NULL);
1348 static int reply_unit_file_changes_and_free(
1351 sd_bus_message *message,
1352 int carries_install_info,
1353 UnitFileChange *changes,
1354 unsigned n_changes) {
1356 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1361 bus_manager_foreach_client(m, send_unit_files_changed, NULL);
1363 r = sd_bus_message_new_method_return(message, &reply);
1367 if (carries_install_info >= 0) {
1368 r = sd_bus_message_append(reply, "b", carries_install_info);
1373 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1377 for (i = 0; i < n_changes; i++) {
1378 r = sd_bus_message_append(
1380 unit_file_change_type_to_string(changes[i].type),
1387 r = sd_bus_message_close_container(reply);
1391 return sd_bus_send(bus, reply, NULL);
1394 unit_file_changes_free(changes, n_changes);
1398 static int method_enable_unit_files_generic(
1400 sd_bus_message *message,
1403 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1404 bool carries_install_info,
1405 sd_bus_error *error) {
1407 _cleanup_strv_free_ char **l = NULL;
1408 UnitFileChange *changes = NULL;
1409 unsigned n_changes = 0;
1410 UnitFileScope scope;
1411 int runtime, force, r;
1417 r = selinux_access_check(bus, message, verb, error);
1421 r = sd_bus_message_read_strv(message, &l);
1425 r = sd_bus_message_read(message, "bb", &runtime, &force);
1429 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1431 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1435 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1438 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1439 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1442 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1443 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1446 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1447 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1450 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1451 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
1454 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1455 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1458 static int method_disable_unit_files_generic(
1460 sd_bus_message *message,
1463 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1464 sd_bus_error *error) {
1466 _cleanup_strv_free_ char **l = NULL;
1467 UnitFileChange *changes = NULL;
1468 unsigned n_changes = 0;
1469 UnitFileScope scope;
1476 r = selinux_access_check(bus, message, verb, error);
1480 r = sd_bus_message_read_strv(message, &l);
1484 r = sd_bus_message_read(message, "b", &runtime);
1488 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1490 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1494 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1497 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1498 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1501 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1502 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1505 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1506 UnitFileChange *changes = NULL;
1507 unsigned n_changes = 0;
1508 Manager *m = userdata;
1509 UnitFileScope scope;
1517 r = selinux_access_check(bus, message, "enable", error);
1521 r = sd_bus_message_read(message, "sb", &name, &force);
1525 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1527 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1531 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1534 const sd_bus_vtable bus_manager_vtable[] = {
1535 SD_BUS_VTABLE_START(0),
1537 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, 0),
1538 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, 0),
1539 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, 0),
1540 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, 0),
1541 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), 0),
1542 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), 0),
1543 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), 0),
1544 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), 0),
1545 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), 0),
1546 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), 0),
1547 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), 0),
1548 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), 0),
1549 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), 0),
1550 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), 0),
1551 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), 0),
1552 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), 0),
1553 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1554 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1555 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1556 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1557 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1558 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1559 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1560 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1561 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), 0),
1562 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), 0),
1563 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), 0),
1564 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
1565 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
1566 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1567 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1569 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1570 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1571 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1572 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
1573 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
1574 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
1575 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
1576 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
1577 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
1578 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
1579 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
1580 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1581 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
1582 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, 0),
1583 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
1584 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1585 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
1586 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1587 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1588 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1589 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1590 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1591 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1592 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1593 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1594 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1595 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
1596 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
1597 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1598 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1599 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1600 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1601 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1602 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1603 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
1604 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
1605 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
1606 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1607 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
1608 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
1609 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
1610 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
1611 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
1612 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
1613 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
1614 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
1615 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
1616 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
1618 SD_BUS_SIGNAL("UnitNew", "so", 0),
1619 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1620 SD_BUS_SIGNAL("JobNew", "uos", 0),
1621 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1622 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1623 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
1624 SD_BUS_SIGNAL("Reloading", "b", 0),
1629 int bus_manager_foreach_client(Manager *m, int (*send_message)(sd_bus *bus, const char *destination, void *userdata), void *userdata) {
1635 n = set_size(m->subscribed);
1639 BusTrackedClient *d;
1641 assert_se(d = set_first(m->subscribed));
1642 return send_message(d->bus, isempty(d->name) ? NULL : d->name, userdata);
1647 /* Send to everybody */
1648 SET_FOREACH(b, m->private_buses, i) {
1649 r = send_message(b, NULL, userdata);
1655 r = send_message(m->api_bus, NULL, userdata);
1663 static int send_finished(sd_bus *bus, const char *destination, void *userdata) {
1664 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1665 usec_t *times = userdata;
1671 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished", &message);
1675 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
1679 return sd_bus_send_to(bus, message, destination, NULL);
1682 void bus_manager_send_finished(
1684 usec_t firmware_usec,
1688 usec_t userspace_usec,
1689 usec_t total_usec) {
1695 r = bus_manager_foreach_client(m, send_finished,
1696 (usec_t[6]) { firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec });
1698 log_debug("Failed to send finished signal: %s", strerror(-r));
1701 static int send_reloading(sd_bus *bus, const char *destination, void *userdata) {
1702 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1707 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading", &message);
1711 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
1715 return sd_bus_send_to(bus, message, destination, NULL);
1718 void bus_manager_send_reloading(Manager *m, bool active) {
1723 r = bus_manager_foreach_client(m, send_reloading, INT_TO_PTR(active));
1725 log_debug("Failed to send reloading signal: %s", strerror(-r));