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 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
346 u = manager_get_unit_by_pid(m, pid);
348 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
350 r = selinux_unit_access_check(u, bus, message, "status", error);
354 path = unit_dbus_path(u);
358 return sd_bus_reply_method_return(message, "o", path);
361 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
362 _cleanup_free_ char *path = NULL;
363 Manager *m = userdata;
372 r = sd_bus_message_read(message, "s", &name);
376 r = manager_load_unit(m, name, NULL, error, &u);
380 r = selinux_unit_access_check(u, bus, message, "status", error);
384 path = unit_dbus_path(u);
388 return sd_bus_reply_method_return(message, "o", path);
391 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) {
400 r = sd_bus_message_read(message, "s", &name);
404 r = manager_load_unit(m, name, NULL, error, &u);
408 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
411 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
412 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
415 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
416 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
419 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
420 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
423 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
424 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
427 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
428 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
431 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
432 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
435 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
436 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
439 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
440 Manager *m = userdata;
441 const char *old_name;
449 r = sd_bus_message_read(message, "s", &old_name);
453 u = manager_get_unit(m, old_name);
454 if (!u || !u->job || u->job->type != JOB_START)
455 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
457 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
460 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
461 Manager *m = userdata;
470 r = sd_bus_message_read(message, "s", &name);
474 u = manager_get_unit(m, name);
476 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
478 return bus_unit_method_kill(bus, message, u, error);
481 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
482 Manager *m = userdata;
491 r = sd_bus_message_read(message, "s", &name);
495 u = manager_get_unit(m, name);
497 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
499 return bus_unit_method_reset_failed(bus, message, u, error);
502 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
503 Manager *m = userdata;
512 r = sd_bus_message_read(message, "s", &name);
516 u = manager_get_unit(m, name);
518 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
520 return bus_unit_method_set_properties(bus, message, u, error);
523 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
524 const char *name, *smode;
525 Manager *m = userdata;
535 r = sd_bus_message_read(message, "ss", &name, &smode);
539 t = unit_name_to_type(name);
541 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
543 if (!unit_vtable[t]->can_transient)
544 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.");
546 mode = job_mode_from_string(smode);
548 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
550 r = manager_load_unit(m, name, NULL, error, &u);
554 r = selinux_unit_access_check(u, bus, message, "start", error);
558 if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
559 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
561 /* OK, the unit failed to load and is unreferenced, now let's
562 * fill in the transient data instead */
563 r = unit_make_transient(u);
567 /* Set our properties */
568 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
572 /* And load this stub fully */
577 manager_dispatch_load_queue(m);
579 /* Finally, start it */
580 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
583 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
584 _cleanup_free_ char *path = NULL;
585 Manager *m = userdata;
594 r = sd_bus_message_read(message, "u", &id);
598 j = manager_get_job(m, id);
600 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
602 r = selinux_unit_access_check(j->unit, bus, message, "status", error);
606 path = job_dbus_path(j);
610 return sd_bus_reply_method_return(message, "o", path);
613 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
614 Manager *m = userdata;
623 r = sd_bus_message_read(message, "u", &id);
627 j = manager_get_job(m, id);
629 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
631 r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
635 job_finish_and_invalidate(j, JOB_CANCELED, true);
637 return sd_bus_reply_method_return(message, NULL);
640 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
641 Manager *m = userdata;
648 r = selinux_access_check(bus, message, "reboot", error);
652 manager_clear_jobs(m);
654 return sd_bus_reply_method_return(message, NULL);
657 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
658 Manager *m = userdata;
665 r = selinux_access_check(bus, message, "reload", error);
669 manager_reset_failed(m);
671 return sd_bus_reply_method_return(message, NULL);
674 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
675 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
676 Manager *m = userdata;
686 r = selinux_access_check(bus, message, "status", error);
690 r = sd_bus_message_new_method_return(message, &reply);
694 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
698 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
699 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
705 following = unit_following(u);
707 unit_path = unit_dbus_path(u);
712 job_path = job_dbus_path(u->job);
717 r = sd_bus_message_append(
718 reply, "(ssssssouso)",
721 unit_load_state_to_string(u->load_state),
722 unit_active_state_to_string(unit_active_state(u)),
723 unit_sub_state_to_string(u),
724 following ? following->id : "",
726 u->job ? u->job->id : 0,
727 u->job ? job_type_to_string(u->job->type) : "",
728 job_path ? job_path : "/");
733 r = sd_bus_message_close_container(reply);
737 return sd_bus_send(bus, reply, NULL);
740 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
741 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
742 Manager *m = userdata;
751 r = selinux_access_check(bus, message, "status", error);
755 r = sd_bus_message_new_method_return(message, &reply);
759 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
763 HASHMAP_FOREACH(j, m->jobs, i) {
764 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
766 job_path = job_dbus_path(j);
770 unit_path = unit_dbus_path(j->unit);
774 r = sd_bus_message_append(
777 job_state_to_string(j->state),
778 job_type_to_string(j->type),
785 r = sd_bus_message_close_container(reply);
789 return sd_bus_send(bus, reply, NULL);
792 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
793 Manager *m = userdata;
800 r = selinux_access_check(bus, message, "status", error);
804 r = bus_client_track(&m->subscribed, bus, sd_bus_message_get_sender(message));
808 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
810 return sd_bus_reply_method_return(message, NULL);
813 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
814 Manager *m = userdata;
821 r = selinux_access_check(bus, message, "status", error);
825 r = bus_client_untrack(m->subscribed, bus, sd_bus_message_get_sender(message));
829 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
831 return sd_bus_reply_method_return(message, NULL);
834 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
835 _cleanup_free_ char *dump = NULL;
836 _cleanup_fclose_ FILE *f = NULL;
837 Manager *m = userdata;
845 r = selinux_access_check(bus, message, "status", error);
849 f = open_memstream(&dump, &size);
853 manager_dump_units(m, f, NULL);
854 manager_dump_jobs(m, f, NULL);
861 return sd_bus_reply_method_return(message, "s", dump);
864 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
865 _cleanup_free_ char *path = NULL;
866 Manager *m = userdata;
876 r = selinux_access_check(bus, message, "start", error);
880 r = sd_bus_message_read(message, "sb", &name, &cleanup);
887 r = snapshot_create(m, name, cleanup, error, &s);
891 path = unit_dbus_path(UNIT(s));
895 return sd_bus_reply_method_return(message, "o", path);
898 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
899 Manager *m = userdata;
908 r = selinux_access_check(bus, message, "stop", error);
912 r = sd_bus_message_read(message, "s", &name);
916 u = manager_get_unit(m, name);
918 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
920 if (u->type != UNIT_SNAPSHOT)
921 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
923 return bus_snapshot_method_remove(bus, message, u, error);
926 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
927 Manager *m = userdata;
934 r = selinux_access_check(bus, message, "reload", error);
938 /* Instead of sending the reply back right away, we just
939 * remember that we need to and then send it after the reload
940 * is finished. That way the caller knows when the reload
943 assert(!m->queued_message);
944 r = sd_bus_message_new_method_return(message, &m->queued_message);
948 m->queued_message_bus = sd_bus_ref(bus);
949 m->exit_code = MANAGER_RELOAD;
954 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
955 Manager *m = userdata;
962 r = selinux_access_check(bus, message, "reload", error);
966 /* We don't send a reply back here, the client should
967 * just wait for us disconnecting. */
969 m->exit_code = MANAGER_REEXECUTE;
973 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
974 Manager *m = userdata;
981 r = selinux_access_check(bus, message, "halt", error);
985 if (m->running_as == SYSTEMD_SYSTEM)
986 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
988 m->exit_code = MANAGER_EXIT;
990 return sd_bus_reply_method_return(message, NULL);
993 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
994 Manager *m = userdata;
1001 r = selinux_access_check(bus, message, "reboot", error);
1005 if (m->running_as != SYSTEMD_SYSTEM)
1006 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1008 m->exit_code = MANAGER_REBOOT;
1010 return sd_bus_reply_method_return(message, NULL);
1014 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1015 Manager *m = userdata;
1022 r = selinux_access_check(bus, message, "halt", error);
1026 if (m->running_as != SYSTEMD_SYSTEM)
1027 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1029 m->exit_code = MANAGER_POWEROFF;
1031 return sd_bus_reply_method_return(message, NULL);
1034 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1035 Manager *m = userdata;
1042 r = selinux_access_check(bus, message, "halt", error);
1046 if (m->running_as != SYSTEMD_SYSTEM)
1047 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1049 m->exit_code = MANAGER_HALT;
1051 return sd_bus_reply_method_return(message, NULL);
1054 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1055 Manager *m = userdata;
1062 r = selinux_access_check(bus, message, "reboot", error);
1066 if (m->running_as != SYSTEMD_SYSTEM)
1067 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1069 m->exit_code = MANAGER_KEXEC;
1071 return sd_bus_reply_method_return(message, NULL);
1074 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1075 char *ri = NULL, *rt = NULL;
1076 const char *root, *init;
1077 Manager *m = userdata;
1084 r = selinux_access_check(bus, message, "reboot", error);
1088 if (m->running_as != SYSTEMD_SYSTEM)
1089 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1091 r = sd_bus_message_read(message, "ss", &root, &init);
1095 if (path_equal(root, "/") || !path_is_absolute(root))
1096 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1099 if (isempty(init)) {
1100 if (! path_is_os_tree(root))
1101 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);
1103 _cleanup_free_ char *p = NULL;
1105 if (!path_is_absolute(init))
1106 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1108 p = strappend(root, init);
1112 if (access(p, X_OK) < 0)
1113 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1120 if (!isempty(init)) {
1128 free(m->switch_root);
1129 m->switch_root = rt;
1131 free(m->switch_root_init);
1132 m->switch_root_init = ri;
1134 return sd_bus_reply_method_return(message, NULL);
1137 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1138 _cleanup_strv_free_ char **plus = NULL;
1139 Manager *m = userdata;
1146 r = selinux_access_check(bus, message, "reload", error);
1150 r = sd_bus_message_read_strv(message, &plus);
1153 if (!strv_env_is_valid(plus))
1154 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1156 r = manager_environment_add(m, NULL, plus);
1160 return sd_bus_reply_method_return(message, NULL);
1163 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1164 _cleanup_strv_free_ char **minus = NULL;
1165 Manager *m = userdata;
1172 r = selinux_access_check(bus, message, "reload", error);
1176 r = sd_bus_message_read_strv(message, &minus);
1180 if (!strv_env_name_or_assignment_is_valid(minus))
1181 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1183 r = manager_environment_add(m, minus, NULL);
1187 return sd_bus_reply_method_return(message, NULL);
1190 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1191 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1192 Manager *m = userdata;
1199 r = selinux_access_check(bus, message, "reload", error);
1203 r = sd_bus_message_read_strv(message, &plus);
1207 r = sd_bus_message_read_strv(message, &minus);
1211 if (!strv_env_is_valid(plus))
1212 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1213 if (!strv_env_name_or_assignment_is_valid(minus))
1214 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1216 r = manager_environment_add(m, minus, plus);
1220 return sd_bus_reply_method_return(message, NULL);
1223 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1224 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1225 Manager *m = userdata;
1235 r = selinux_access_check(bus, message, "status", error);
1239 r = sd_bus_message_new_method_return(message, &reply);
1243 h = hashmap_new(string_hash_func, string_compare_func);
1247 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1251 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1255 HASHMAP_FOREACH(item, h, i) {
1257 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1262 unit_file_list_free(h);
1264 r = sd_bus_message_close_container(reply);
1268 return sd_bus_send(bus, reply, NULL);
1271 unit_file_list_free(h);
1275 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1276 Manager *m = userdata;
1278 UnitFileState state;
1279 UnitFileScope scope;
1286 r = selinux_access_check(bus, message, "status", error);
1290 r = sd_bus_message_read(message, "s", &name);
1294 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1296 state = unit_file_get_state(scope, NULL, name);
1300 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1303 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1304 _cleanup_free_ char *default_target = NULL;
1305 Manager *m = userdata;
1306 UnitFileScope scope;
1313 r = selinux_access_check(bus, message, "status", error);
1317 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1319 r = unit_file_get_default(scope, NULL, &default_target);
1323 return sd_bus_reply_method_return(message, "s", default_target);
1326 static int send_unit_files_changed(sd_bus *bus, const char *destination, void *userdata) {
1327 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1332 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged", &message);
1336 return sd_bus_send_to(bus, message, destination, NULL);
1339 static int reply_unit_file_changes_and_free(
1342 sd_bus_message *message,
1343 int carries_install_info,
1344 UnitFileChange *changes,
1345 unsigned n_changes) {
1347 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1352 bus_manager_foreach_client(m, send_unit_files_changed, NULL);
1354 r = sd_bus_message_new_method_return(message, &reply);
1358 if (carries_install_info >= 0) {
1359 r = sd_bus_message_append(reply, "b", carries_install_info);
1364 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1368 for (i = 0; i < n_changes; i++) {
1369 r = sd_bus_message_append(
1371 unit_file_change_type_to_string(changes[i].type),
1378 r = sd_bus_message_close_container(reply);
1382 return sd_bus_send(bus, reply, NULL);
1385 unit_file_changes_free(changes, n_changes);
1389 static int method_enable_unit_files_generic(
1391 sd_bus_message *message,
1394 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1395 bool carries_install_info,
1396 sd_bus_error *error) {
1398 _cleanup_strv_free_ char **l = NULL;
1399 UnitFileChange *changes = NULL;
1400 unsigned n_changes = 0;
1401 UnitFileScope scope;
1402 int runtime, force, r;
1408 r = selinux_access_check(bus, message, verb, error);
1412 r = sd_bus_message_read_strv(message, &l);
1416 r = sd_bus_message_read(message, "bb", &runtime, &force);
1420 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1422 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1426 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1429 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1430 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1433 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1434 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1437 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1438 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1441 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1442 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
1445 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1446 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1449 static int method_disable_unit_files_generic(
1451 sd_bus_message *message,
1454 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1455 sd_bus_error *error) {
1457 _cleanup_strv_free_ char **l = NULL;
1458 UnitFileChange *changes = NULL;
1459 unsigned n_changes = 0;
1460 UnitFileScope scope;
1467 r = selinux_access_check(bus, message, verb, error);
1471 r = sd_bus_message_read_strv(message, &l);
1475 r = sd_bus_message_read(message, "b", &runtime);
1479 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1481 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1485 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1488 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1489 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1492 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1493 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1496 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1497 UnitFileChange *changes = NULL;
1498 unsigned n_changes = 0;
1499 Manager *m = userdata;
1500 UnitFileScope scope;
1508 r = selinux_access_check(bus, message, "enable", error);
1512 r = sd_bus_message_read(message, "sb", &name, &force);
1516 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1518 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1522 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1525 const sd_bus_vtable bus_manager_vtable[] = {
1526 SD_BUS_VTABLE_START(0),
1528 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, 0),
1529 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, 0),
1530 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, 0),
1531 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, 0),
1532 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), 0),
1533 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), 0),
1534 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, firmware_timestamp), 0),
1535 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), 0),
1536 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), 0),
1537 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), 0),
1538 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), 0),
1539 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), 0),
1540 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), 0),
1541 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), 0),
1542 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), 0),
1543 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), 0),
1544 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1545 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1546 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1547 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1548 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1549 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1550 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1551 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1552 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), 0),
1553 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), 0),
1554 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), 0),
1555 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
1556 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
1557 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1558 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1560 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, 0),
1561 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, 0),
1562 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, 0),
1563 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
1564 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
1565 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
1566 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
1567 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
1568 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
1569 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
1570 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
1571 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, 0),
1572 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
1573 SD_BUS_METHOD("SetUnitProperties", "sb", "a(sv)", method_set_unit_properties, 0),
1574 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
1575 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, 0),
1576 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
1577 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1578 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1579 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, 0),
1580 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, 0),
1581 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, 0),
1582 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, 0),
1583 SD_BUS_METHOD("Dump", NULL, "s", method_dump, 0),
1584 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1585 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1586 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
1587 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
1588 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1589 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, 0),
1590 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, 0),
1591 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, 0),
1592 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, 0),
1593 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, 0),
1594 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
1595 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
1596 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
1597 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, 0),
1598 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, 0),
1599 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
1600 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
1601 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
1602 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
1603 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
1604 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
1605 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
1606 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
1607 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, 0),
1609 SD_BUS_SIGNAL("UnitNew", "so", 0),
1610 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1611 SD_BUS_SIGNAL("JobNew", "uos", 0),
1612 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1613 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1614 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
1615 SD_BUS_SIGNAL("Reloading", "b", 0),
1620 int bus_manager_foreach_client(Manager *m, int (*send_message)(sd_bus *bus, const char *destination, void *userdata), void *userdata) {
1626 n = set_size(m->subscribed);
1630 BusTrackedClient *d;
1632 assert_se(d = set_first(m->subscribed));
1633 return send_message(d->bus, isempty(d->name) ? NULL : d->name, userdata);
1636 /* Send to everybody */
1637 SET_FOREACH(b, m->private_buses, i) {
1638 r = send_message(b, NULL, userdata);
1644 return send_message(m->api_bus, NULL, userdata);
1649 static int send_finished(sd_bus *bus, const char *destination, void *userdata) {
1650 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1651 usec_t *times = userdata;
1657 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished", &message);
1661 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
1665 return sd_bus_send_to(bus, message, destination, NULL);
1668 int bus_manager_send_finished(
1670 usec_t firmware_usec,
1674 usec_t userspace_usec,
1675 usec_t total_usec) {
1679 return bus_manager_foreach_client(m, send_finished,
1680 (usec_t[6]) { firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec });
1683 static int send_reloading(sd_bus *bus, const char *destination, void *userdata) {
1684 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1689 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading", &message);
1693 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
1697 return sd_bus_send_to(bus, message, destination, NULL);
1700 int bus_manager_send_reloading(Manager *m, bool active) {
1703 return bus_manager_foreach_client(m, send_reloading, INT_TO_PTR(active));