udev: String substitutions can be done in ENV, too
[systemd_ALT.git] / src / core / dbus-manager.c
blob1204b913c9e4cc16a09fdab346df02fe51e22f09
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <errno.h>
4 #include <sys/prctl.h>
5 #include <sys/statvfs.h>
6 #include <unistd.h>
8 #include "alloc-util.h"
9 #include "architecture.h"
10 #include "build.h"
11 #include "bus-common-errors.h"
12 #include "bus-get-properties.h"
13 #include "bus-log-control-api.h"
14 #include "chase.h"
15 #include "confidential-virt.h"
16 #include "data-fd-util.h"
17 #include "dbus-cgroup.h"
18 #include "dbus-execute.h"
19 #include "dbus-job.h"
20 #include "dbus-manager.h"
21 #include "dbus-scope.h"
22 #include "dbus-service.h"
23 #include "dbus-unit.h"
24 #include "dbus.h"
25 #include "env-util.h"
26 #include "fd-util.h"
27 #include "fileio.h"
28 #include "format-util.h"
29 #include "install.h"
30 #include "log.h"
31 #include "manager-dump.h"
32 #include "os-util.h"
33 #include "parse-util.h"
34 #include "path-util.h"
35 #include "process-util.h"
36 #include "selinux-access.h"
37 #include "stat-util.h"
38 #include "string-util.h"
39 #include "strv.h"
40 #include "syslog-util.h"
41 #include "user-util.h"
42 #include "virt.h"
43 #include "watchdog.h"
45 /* Require 16MiB free in /run/systemd for reloading/reexecing. After all we need to serialize our state
46 * there, and if we can't we'll fail badly. */
47 #define RELOAD_DISK_SPACE_MIN (UINT64_C(16) * UINT64_C(1024) * UINT64_C(1024))
49 static UnitFileFlags unit_file_bools_to_flags(bool runtime, bool force) {
50 return (runtime ? UNIT_FILE_RUNTIME : 0) |
51 (force ? UNIT_FILE_FORCE : 0);
54 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_oom_policy, oom_policy, OOMPolicy);
55 BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_emergency_action, emergency_action, EmergencyAction);
57 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_version, "s", GIT_VERSION);
58 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_features, "s", systemd_features);
59 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_architecture, "s", architecture_to_string(uname_architecture()));
60 static BUS_DEFINE_PROPERTY_GET2(property_get_system_state, "s", Manager, manager_state, manager_state_to_string);
61 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_timer_slack_nsec, "t", (uint64_t) prctl(PR_GET_TIMERSLACK));
62 static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "u", Hashmap *, hashmap_size);
63 static BUS_DEFINE_PROPERTY_GET_REF(property_get_set_size, "u", Set *, set_size);
64 static BUS_DEFINE_PROPERTY_GET(property_get_default_timeout_abort_usec, "t", Manager, manager_default_timeout_abort_usec);
65 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_device, "s", watchdog_get_device());
66 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_last_ping_realtime, "t", watchdog_get_last_ping(CLOCK_REALTIME));
67 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_watchdog_last_ping_monotonic, "t", watchdog_get_last_ping(CLOCK_MONOTONIC));
69 static int property_get_virtualization(
70 sd_bus *bus,
71 const char *path,
72 const char *interface,
73 const char *property,
74 sd_bus_message *reply,
75 void *userdata,
76 sd_bus_error *error) {
78 Virtualization v;
80 assert(bus);
81 assert(reply);
83 v = detect_virtualization();
85 /* Make sure to return the empty string when we detect no virtualization, as that is the API.
87 * https://github.com/systemd/systemd/issues/1423
90 return sd_bus_message_append(
91 reply, "s",
92 v == VIRTUALIZATION_NONE ? NULL : virtualization_to_string(v));
95 static int property_get_confidential_virtualization(
96 sd_bus *bus,
97 const char *path,
98 const char *interface,
99 const char *property,
100 sd_bus_message *reply,
101 void *userdata,
102 sd_bus_error *error) {
104 ConfidentialVirtualization v;
106 assert(bus);
107 assert(reply);
109 v = detect_confidential_virtualization();
111 return sd_bus_message_append(
112 reply, "s",
113 v <= 0 ? NULL : confidential_virtualization_to_string(v));
116 static int property_get_tainted(
117 sd_bus *bus,
118 const char *path,
119 const char *interface,
120 const char *property,
121 sd_bus_message *reply,
122 void *userdata,
123 sd_bus_error *error) {
125 _cleanup_free_ char *s = NULL;
126 Manager *m = ASSERT_PTR(userdata);
128 assert(bus);
129 assert(reply);
131 s = manager_taint_string(m);
132 if (!s)
133 return log_oom();
135 return sd_bus_message_append(reply, "s", s);
138 static int property_set_log_target(
139 sd_bus *bus,
140 const char *path,
141 const char *interface,
142 const char *property,
143 sd_bus_message *value,
144 void *userdata,
145 sd_bus_error *error) {
147 Manager *m = userdata;
148 const char *t;
149 int r;
151 assert(bus);
152 assert(value);
154 r = sd_bus_message_read(value, "s", &t);
155 if (r < 0)
156 return r;
158 if (isempty(t))
159 manager_restore_original_log_target(m);
160 else {
161 LogTarget target;
163 target = log_target_from_string(t);
164 if (target < 0)
165 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log target '%s'", t);
167 manager_override_log_target(m, target);
170 return 0;
173 static int property_set_log_level(
174 sd_bus *bus,
175 const char *path,
176 const char *interface,
177 const char *property,
178 sd_bus_message *value,
179 void *userdata,
180 sd_bus_error *error) {
182 Manager *m = userdata;
183 const char *t;
184 int r;
186 assert(bus);
187 assert(value);
189 r = sd_bus_message_read(value, "s", &t);
190 if (r < 0)
191 return r;
193 if (isempty(t))
194 manager_restore_original_log_level(m);
195 else {
196 int level;
198 level = log_level_from_string(t);
199 if (level < 0)
200 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log level '%s'", t);
202 manager_override_log_level(m, level);
205 return 0;
208 static int property_get_progress(
209 sd_bus *bus,
210 const char *path,
211 const char *interface,
212 const char *property,
213 sd_bus_message *reply,
214 void *userdata,
215 sd_bus_error *error) {
217 Manager *m = ASSERT_PTR(userdata);
218 double d;
220 assert(bus);
221 assert(reply);
223 if (MANAGER_IS_FINISHED(m))
224 d = 1.0;
225 else
226 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
228 return sd_bus_message_append(reply, "d", d);
231 static int property_get_environment(
232 sd_bus *bus,
233 const char *path,
234 const char *interface,
235 const char *property,
236 sd_bus_message *reply,
237 void *userdata,
238 sd_bus_error *error) {
240 _cleanup_strv_free_ char **l = NULL;
241 Manager *m = ASSERT_PTR(userdata);
242 int r;
244 assert(bus);
245 assert(reply);
247 r = manager_get_effective_environment(m, &l);
248 if (r < 0)
249 return r;
251 return sd_bus_message_append_strv(reply, l);
254 static int property_get_show_status(
255 sd_bus *bus,
256 const char *path,
257 const char *interface,
258 const char *property,
259 sd_bus_message *reply,
260 void *userdata,
261 sd_bus_error *error) {
263 Manager *m = ASSERT_PTR(userdata);
265 assert(bus);
266 assert(reply);
268 return sd_bus_message_append(reply, "b", manager_get_show_status_on(m));
271 static int property_get_runtime_watchdog(
272 sd_bus *bus,
273 const char *path,
274 const char *interface,
275 const char *property,
276 sd_bus_message *reply,
277 void *userdata,
278 sd_bus_error *error) {
280 Manager *m = ASSERT_PTR(userdata);
282 assert(bus);
283 assert(reply);
285 return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_RUNTIME));
288 static int property_get_pretimeout_watchdog(
289 sd_bus *bus,
290 const char *path,
291 const char *interface,
292 const char *property,
293 sd_bus_message *reply,
294 void *userdata,
295 sd_bus_error *error) {
297 Manager *m = ASSERT_PTR(userdata);
299 assert(bus);
300 assert(reply);
302 return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_PRETIMEOUT));
305 static int property_get_pretimeout_watchdog_governor(
306 sd_bus *bus,
307 const char *path,
308 const char *interface,
309 const char *property,
310 sd_bus_message *reply,
311 void *userdata,
312 sd_bus_error *error) {
314 Manager *m = ASSERT_PTR(userdata);
316 assert(bus);
317 assert(reply);
319 return sd_bus_message_append(reply, "s", m->watchdog_pretimeout_governor);
322 static int property_get_reboot_watchdog(
323 sd_bus *bus,
324 const char *path,
325 const char *interface,
326 const char *property,
327 sd_bus_message *reply,
328 void *userdata,
329 sd_bus_error *error) {
331 Manager *m = ASSERT_PTR(userdata);
333 assert(bus);
334 assert(reply);
336 return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_REBOOT));
339 static int property_get_kexec_watchdog(
340 sd_bus *bus,
341 const char *path,
342 const char *interface,
343 const char *property,
344 sd_bus_message *reply,
345 void *userdata,
346 sd_bus_error *error) {
348 Manager *m = ASSERT_PTR(userdata);
350 assert(bus);
351 assert(reply);
353 return sd_bus_message_append(reply, "t", manager_get_watchdog(m, WATCHDOG_KEXEC));
356 static int property_set_watchdog(Manager *m, WatchdogType type, sd_bus_message *value) {
357 usec_t timeout;
358 int r;
360 assert(m);
361 assert(value);
363 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
365 r = sd_bus_message_read(value, "t", &timeout);
366 if (r < 0)
367 return r;
369 manager_override_watchdog(m, type, timeout);
370 return 0;
373 static int property_set_runtime_watchdog(
374 sd_bus *bus,
375 const char *path,
376 const char *interface,
377 const char *property,
378 sd_bus_message *value,
379 void *userdata,
380 sd_bus_error *error) {
382 return property_set_watchdog(userdata, WATCHDOG_RUNTIME, value);
385 static int property_set_pretimeout_watchdog(
386 sd_bus *bus,
387 const char *path,
388 const char *interface,
389 const char *property,
390 sd_bus_message *value,
391 void *userdata,
392 sd_bus_error *error) {
394 return property_set_watchdog(userdata, WATCHDOG_PRETIMEOUT, value);
397 static int property_set_pretimeout_watchdog_governor(
398 sd_bus *bus,
399 const char *path,
400 const char *interface,
401 const char *property,
402 sd_bus_message *value,
403 void *userdata,
404 sd_bus_error *error) {
406 Manager *m = ASSERT_PTR(userdata);
407 char *governor;
408 int r;
410 r = sd_bus_message_read(value, "s", &governor);
411 if (r < 0)
412 return r;
413 if (!string_is_safe(governor))
414 return -EINVAL;
416 return manager_override_watchdog_pretimeout_governor(m, governor);
419 static int property_set_reboot_watchdog(
420 sd_bus *bus,
421 const char *path,
422 const char *interface,
423 const char *property,
424 sd_bus_message *value,
425 void *userdata,
426 sd_bus_error *error) {
428 return property_set_watchdog(userdata, WATCHDOG_REBOOT, value);
431 static int property_set_kexec_watchdog(
432 sd_bus *bus,
433 const char *path,
434 const char *interface,
435 const char *property,
436 sd_bus_message *value,
437 void *userdata,
438 sd_bus_error *error) {
440 _unused_ Manager *m = ASSERT_PTR(userdata);
442 assert(bus);
443 assert(value);
445 return property_set_watchdog(userdata, WATCHDOG_KEXEC, value);
448 static int property_get_oom_score_adjust(
449 sd_bus *bus,
450 const char *path,
451 const char *interface,
452 const char *property,
453 sd_bus_message *reply,
454 void *userdata,
455 sd_bus_error *error) {
457 Manager *m = ASSERT_PTR(userdata);
458 int r, n;
460 assert(bus);
461 assert(reply);
463 if (m->default_oom_score_adjust_set)
464 n = m->default_oom_score_adjust;
465 else {
466 n = 0;
467 r = get_oom_score_adjust(&n);
468 if (r < 0)
469 log_debug_errno(r, "Failed to read current OOM score adjustment value, ignoring: %m");
472 return sd_bus_message_append(reply, "i", n);
475 static int bus_get_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
476 Unit *u;
477 int r;
479 assert(m);
480 assert(message);
481 assert(ret_unit);
483 /* More or less a wrapper around manager_get_unit() that generates nice errors and has one trick up
484 * its sleeve: if the name is specified empty we use the client's unit. */
486 if (isempty(name)) {
487 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
488 pid_t pid;
490 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
491 if (r < 0)
492 return r;
494 r = sd_bus_creds_get_pid(creds, &pid);
495 if (r < 0)
496 return r;
498 u = manager_get_unit_by_pid(m, pid);
499 if (!u)
500 return sd_bus_error_set(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
501 } else {
502 u = manager_get_unit(m, name);
503 if (!u)
504 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
507 *ret_unit = u;
508 return 0;
511 static int bus_load_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
512 assert(m);
513 assert(message);
514 assert(ret_unit);
516 /* Pretty much the same as bus_get_unit_by_name(), but we also load the unit if necessary. */
518 if (isempty(name))
519 return bus_get_unit_by_name(m, message, name, ret_unit, error);
521 return manager_load_unit(m, name, NULL, error, ret_unit);
524 static int reply_unit_path(Unit *u, sd_bus_message *message, sd_bus_error *error) {
525 _cleanup_free_ char *path = NULL;
526 int r;
528 assert(u);
529 assert(message);
531 r = mac_selinux_unit_access_check(u, message, "status", error);
532 if (r < 0)
533 return r;
535 path = unit_dbus_path(u);
536 if (!path)
537 return log_oom();
539 return sd_bus_reply_method_return(message, "o", path);
542 static int method_get_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
543 Manager *m = ASSERT_PTR(userdata);
544 const char *name;
545 Unit *u;
546 int r;
548 assert(message);
550 /* Anyone can call this method */
552 r = sd_bus_message_read(message, "s", &name);
553 if (r < 0)
554 return r;
556 r = bus_get_unit_by_name(m, message, name, &u, error);
557 if (r < 0)
558 return r;
560 return reply_unit_path(u, message, error);
563 static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
564 Manager *m = ASSERT_PTR(userdata);
565 pid_t pid;
566 Unit *u;
567 int r;
569 assert(message);
571 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
573 /* Anyone can call this method */
575 r = sd_bus_message_read(message, "u", &pid);
576 if (r < 0)
577 return r;
578 if (pid < 0)
579 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
581 if (pid == 0) {
582 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
584 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
585 if (r < 0)
586 return r;
588 r = sd_bus_creds_get_pid(creds, &pid);
589 if (r < 0)
590 return r;
593 u = manager_get_unit_by_pid(m, pid);
594 if (!u)
595 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
597 return reply_unit_path(u, message, error);
600 static int method_get_unit_by_invocation_id(sd_bus_message *message, void *userdata, sd_bus_error *error) {
601 _cleanup_free_ char *path = NULL;
602 Manager *m = ASSERT_PTR(userdata);
603 sd_id128_t id;
604 const void *a;
605 Unit *u;
606 size_t sz;
607 int r;
609 assert(message);
611 /* Anyone can call this method */
613 r = sd_bus_message_read_array(message, 'y', &a, &sz);
614 if (r < 0)
615 return r;
616 if (sz == 0)
617 id = SD_ID128_NULL;
618 else if (sz == 16)
619 memcpy(&id, a, sz);
620 else
621 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid invocation ID");
623 if (sd_id128_is_null(id)) {
624 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
625 pid_t pid;
627 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
628 if (r < 0)
629 return r;
631 r = sd_bus_creds_get_pid(creds, &pid);
632 if (r < 0)
633 return r;
635 u = manager_get_unit_by_pid(m, pid);
636 if (!u)
637 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT,
638 "Client " PID_FMT " not member of any unit.", pid);
639 } else {
640 u = hashmap_get(m->units_by_invocation_id, &id);
641 if (!u)
642 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(id));
645 r = mac_selinux_unit_access_check(u, message, "status", error);
646 if (r < 0)
647 return r;
649 /* So here's a special trick: the bus path we return actually references the unit by its invocation
650 * ID instead of the unit name. This means it stays valid only as long as the invocation ID stays the
651 * same. */
652 path = unit_dbus_path_invocation_id(u);
653 if (!path)
654 return -ENOMEM;
656 return sd_bus_reply_method_return(message, "o", path);
659 static int method_get_unit_by_control_group(sd_bus_message *message, void *userdata, sd_bus_error *error) {
660 Manager *m = userdata;
661 const char *cgroup;
662 Unit *u;
663 int r;
665 r = sd_bus_message_read(message, "s", &cgroup);
666 if (r < 0)
667 return r;
669 u = manager_get_unit_by_cgroup(m, cgroup);
670 if (!u)
671 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT,
672 "Control group '%s' is not valid or not managed by this instance",
673 cgroup);
675 return reply_unit_path(u, message, error);
678 static int method_get_unit_by_pidfd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
679 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
680 Manager *m = ASSERT_PTR(userdata);
681 _cleanup_free_ char *path = NULL;
682 int r, pidfd;
683 pid_t pid;
684 Unit *u;
686 assert(message);
688 r = sd_bus_message_read(message, "h", &pidfd);
689 if (r < 0)
690 return r;
692 r = pidfd_get_pid(pidfd, &pid);
693 if (r < 0)
694 return sd_bus_error_set_errnof(error, r, "Failed to get PID from PIDFD: %m");
696 u = manager_get_unit_by_pid(m, pid);
697 if (!u)
698 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
700 r = mac_selinux_unit_access_check(u, message, "status", error);
701 if (r < 0)
702 return r;
704 path = unit_dbus_path(u);
705 if (!path)
706 return log_oom();
708 r = sd_bus_message_new_method_return(message, &reply);
709 if (r < 0)
710 return r;
712 r = sd_bus_message_append(reply, "os", path, u->id);
713 if (r < 0)
714 return r;
716 r = sd_bus_message_append_array(reply, 'y', u->invocation_id.bytes, sizeof(u->invocation_id.bytes));
717 if (r < 0)
718 return r;
720 /* Double-check that the process is still alive and that the PID did not change before returning the
721 * answer. */
722 r = pidfd_verify_pid(pidfd, pid);
723 if (r == -ESRCH)
724 return sd_bus_error_setf(error,
725 BUS_ERROR_NO_SUCH_PROCESS,
726 "The PIDFD's PID "PID_FMT" changed during the lookup operation.",
727 pid);
728 if (r < 0)
729 return sd_bus_error_set_errnof(error, r, "Failed to get PID from PIDFD: %m");
731 return sd_bus_send(NULL, reply, NULL);
734 static int method_load_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
735 Manager *m = ASSERT_PTR(userdata);
736 const char *name;
737 Unit *u;
738 int r;
740 assert(message);
742 /* Anyone can call this method */
744 r = sd_bus_message_read(message, "s", &name);
745 if (r < 0)
746 return r;
748 r = bus_load_unit_by_name(m, message, name, &u, error);
749 if (r < 0)
750 return r;
752 return reply_unit_path(u, message, error);
755 static int method_start_unit_generic(sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
756 const char *name;
757 Unit *u;
758 int r;
760 assert(message);
761 assert(m);
763 r = sd_bus_message_read(message, "s", &name);
764 if (r < 0)
765 return r;
767 r = manager_load_unit(m, name, NULL, error, &u);
768 if (r < 0)
769 return r;
771 return bus_unit_method_start_generic(message, u, job_type, reload_if_possible, error);
774 static int method_start_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
775 return method_start_unit_generic(message, userdata, JOB_START, /* reload_if_possible = */ false, error);
778 static int method_stop_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
779 return method_start_unit_generic(message, userdata, JOB_STOP, /* reload_if_possible = */ false, error);
782 static int method_reload_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
783 return method_start_unit_generic(message, userdata, JOB_RELOAD, /* reload_if_possible = */ false, error);
786 static int method_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
787 return method_start_unit_generic(message, userdata, JOB_RESTART, /* reload_if_possible = */ false, error);
790 static int method_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
791 return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, /* reload_if_possible = */ false, error);
794 static int method_reload_or_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
795 return method_start_unit_generic(message, userdata, JOB_RESTART, /* reload_if_possible = */ true, error);
798 static int method_reload_or_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
799 return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, /* reload_if_possible = */ true, error);
802 typedef enum GenericUnitOperationFlags {
803 GENERIC_UNIT_LOAD = 1 << 0, /* Load if the unit is not loaded yet */
804 GENERIC_UNIT_VALIDATE_LOADED = 1 << 1, /* Verify unit is properly loaded before forwarding call */
805 } GenericUnitOperationFlags;
807 static int method_generic_unit_operation(
808 sd_bus_message *message,
809 Manager *m,
810 sd_bus_error *error,
811 sd_bus_message_handler_t handler,
812 GenericUnitOperationFlags flags) {
814 const char *name;
815 Unit *u;
816 int r;
818 assert(message);
819 assert(m);
821 /* Read the first argument from the command and pass the operation to the specified per-unit
822 * method. */
824 r = sd_bus_message_read(message, "s", &name);
825 if (r < 0)
826 return r;
828 if (!isempty(name) && FLAGS_SET(flags, GENERIC_UNIT_LOAD))
829 r = manager_load_unit(m, name, NULL, error, &u);
830 else
831 r = bus_get_unit_by_name(m, message, name, &u, error);
832 if (r < 0)
833 return r;
835 if (FLAGS_SET(flags, GENERIC_UNIT_VALIDATE_LOADED)) {
836 r = bus_unit_validate_load_state(u, error);
837 if (r < 0)
838 return r;
841 return handler(message, u, error);
844 static int method_enqueue_unit_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
845 /* We don't bother with GENERIC_UNIT_VALIDATE_LOADED here, as the job logic validates that anyway */
846 return method_generic_unit_operation(message, userdata, error, bus_unit_method_enqueue_job, GENERIC_UNIT_LOAD);
849 static int method_start_unit_replace(sd_bus_message *message, void *userdata, sd_bus_error *error) {
850 Manager *m = ASSERT_PTR(userdata);
851 const char *old_name;
852 Unit *u;
853 int r;
855 assert(message);
857 r = sd_bus_message_read(message, "s", &old_name);
858 if (r < 0)
859 return r;
861 r = bus_get_unit_by_name(m, message, old_name, &u, error);
862 if (r < 0)
863 return r;
864 if (!u->job || u->job->type != JOB_START)
865 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
867 return method_start_unit_generic(message, m, JOB_START, /* reload_if_possible = */ false, error);
870 static int method_kill_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
871 /* We don't bother with GENERIC_UNIT_LOAD nor GENERIC_UNIT_VALIDATE_LOADED here, as it shouldn't
872 * matter whether a unit is loaded for killing any processes possibly in the unit's cgroup. */
873 return method_generic_unit_operation(message, userdata, error, bus_unit_method_kill, 0);
876 static int method_clean_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
877 /* Load the unit if necessary, in order to load it, and insist on the unit being loaded to be
878 * cleaned */
879 return method_generic_unit_operation(message, userdata, error, bus_unit_method_clean, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
882 static int method_freeze_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
883 return method_generic_unit_operation(message, userdata, error, bus_unit_method_freeze, 0);
886 static int method_thaw_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
887 return method_generic_unit_operation(message, userdata, error, bus_unit_method_thaw, 0);
890 static int method_reset_failed_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
891 /* Don't load the unit (because unloaded units can't be in failed state), and don't insist on the
892 * unit to be loaded properly (since a failed unit might have its unit file disappeared) */
893 return method_generic_unit_operation(message, userdata, error, bus_unit_method_reset_failed, 0);
896 static int method_set_unit_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
897 /* Only change properties on fully loaded units, and load them in order to set properties */
898 return method_generic_unit_operation(message, userdata, error, bus_unit_method_set_properties, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
901 static int method_bind_mount_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
902 /* Only add mounts on fully loaded units */
903 return method_generic_unit_operation(message, userdata, error, bus_service_method_bind_mount, GENERIC_UNIT_VALIDATE_LOADED);
906 static int method_mount_image_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
907 /* Only add mounts on fully loaded units */
908 return method_generic_unit_operation(message, userdata, error, bus_service_method_mount_image, GENERIC_UNIT_VALIDATE_LOADED);
911 static int method_ref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
912 /* Only allow reffing of fully loaded units, and make sure reffing a unit loads it. */
913 return method_generic_unit_operation(message, userdata, error, bus_unit_method_ref, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
916 static int method_unref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
917 /* Dropping a ref OTOH should not require the unit to still be loaded. And since a reffed unit is a
918 * loaded unit there's no need to load the unit for unreffing it. */
919 return method_generic_unit_operation(message, userdata, error, bus_unit_method_unref, 0);
922 static int reply_unit_info(sd_bus_message *reply, Unit *u) {
923 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
924 Unit *following;
926 following = unit_following(u);
928 unit_path = unit_dbus_path(u);
929 if (!unit_path)
930 return -ENOMEM;
932 if (u->job) {
933 job_path = job_dbus_path(u->job);
934 if (!job_path)
935 return -ENOMEM;
938 return sd_bus_message_append(
939 reply, "(ssssssouso)",
940 u->id,
941 unit_description(u),
942 unit_load_state_to_string(u->load_state),
943 unit_active_state_to_string(unit_active_state(u)),
944 unit_sub_state_to_string(u),
945 following ? following->id : "",
946 unit_path,
947 u->job ? u->job->id : 0,
948 u->job ? job_type_to_string(u->job->type) : "",
949 empty_to_root(job_path));
952 static int method_list_units_by_names(sd_bus_message *message, void *userdata, sd_bus_error *error) {
953 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
954 Manager *m = ASSERT_PTR(userdata);
955 int r;
956 _cleanup_strv_free_ char **units = NULL;
958 assert(message);
960 r = sd_bus_message_read_strv(message, &units);
961 if (r < 0)
962 return r;
964 r = sd_bus_message_new_method_return(message, &reply);
965 if (r < 0)
966 return r;
968 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
969 if (r < 0)
970 return r;
972 STRV_FOREACH(unit, units) {
973 Unit *u;
975 if (!unit_name_is_valid(*unit, UNIT_NAME_ANY))
976 continue;
978 r = bus_load_unit_by_name(m, message, *unit, &u, error);
979 if (r < 0)
980 return r;
982 r = reply_unit_info(reply, u);
983 if (r < 0)
984 return r;
987 r = sd_bus_message_close_container(reply);
988 if (r < 0)
989 return r;
991 return sd_bus_send(NULL, reply, NULL);
994 static int method_get_unit_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
995 /* Don't load a unit (since it won't have any processes if it's not loaded), but don't insist on the
996 * unit being loaded (because even improperly loaded units might still have processes around */
997 return method_generic_unit_operation(message, userdata, error, bus_unit_method_get_processes, 0);
1000 static int method_attach_processes_to_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1001 /* Don't allow attaching new processes to units that aren't loaded. Don't bother with loading a unit
1002 * for this purpose though, as an unloaded unit is a stopped unit, and we don't allow attaching
1003 * processes to stopped units anyway. */
1004 return method_generic_unit_operation(message, userdata, error, bus_unit_method_attach_processes, GENERIC_UNIT_VALIDATE_LOADED);
1007 static int transient_unit_from_message(
1008 Manager *m,
1009 sd_bus_message *message,
1010 const char *name,
1011 Unit **unit,
1012 sd_bus_error *error) {
1014 UnitType t;
1015 Unit *u;
1016 int r;
1018 assert(m);
1019 assert(message);
1020 assert(name);
1022 t = unit_name_to_type(name);
1023 if (t < 0)
1024 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1025 "Invalid unit name or type.");
1027 if (!unit_vtable[t]->can_transient)
1028 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1029 "Unit type %s does not support transient units.",
1030 unit_type_to_string(t));
1032 r = manager_load_unit(m, name, NULL, error, &u);
1033 if (r < 0)
1034 return r;
1036 if (!unit_is_pristine(u))
1037 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
1038 "Unit %s was already loaded or has a fragment file.", name);
1040 /* OK, the unit failed to load and is unreferenced, now let's
1041 * fill in the transient data instead */
1042 r = unit_make_transient(u);
1043 if (r < 0)
1044 return r;
1046 /* Set our properties */
1047 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
1048 if (r < 0)
1049 return r;
1051 /* If the client asked for it, automatically add a reference to this unit. */
1052 if (u->bus_track_add) {
1053 r = bus_unit_track_add_sender(u, message);
1054 if (r < 0)
1055 return log_error_errno(r, "Failed to watch sender: %m");
1058 /* Now load the missing bits of the unit we just created */
1059 unit_add_to_load_queue(u);
1060 manager_dispatch_load_queue(m);
1062 *unit = u;
1064 return 0;
1067 static int transient_aux_units_from_message(
1068 Manager *m,
1069 sd_bus_message *message,
1070 sd_bus_error *error) {
1072 int r;
1074 assert(m);
1075 assert(message);
1077 r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
1078 if (r < 0)
1079 return r;
1081 while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
1082 const char *name = NULL;
1083 Unit *u;
1085 r = sd_bus_message_read(message, "s", &name);
1086 if (r < 0)
1087 return r;
1089 r = transient_unit_from_message(m, message, name, &u, error);
1090 if (r < 0)
1091 return r;
1093 r = sd_bus_message_exit_container(message);
1094 if (r < 0)
1095 return r;
1097 if (r < 0)
1098 return r;
1100 r = sd_bus_message_exit_container(message);
1101 if (r < 0)
1102 return r;
1104 return 0;
1107 static int method_start_transient_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1108 const char *name, *smode;
1109 Manager *m = ASSERT_PTR(userdata);
1110 JobMode mode;
1111 Unit *u;
1112 int r;
1114 assert(message);
1116 r = mac_selinux_access_check(message, "start", error);
1117 if (r < 0)
1118 return r;
1120 r = sd_bus_message_read(message, "ss", &name, &smode);
1121 if (r < 0)
1122 return r;
1124 mode = job_mode_from_string(smode);
1125 if (mode < 0)
1126 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
1128 r = bus_verify_manage_units_async(m, message, error);
1129 if (r < 0)
1130 return r;
1131 if (r == 0)
1132 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1134 r = transient_unit_from_message(m, message, name, &u, error);
1135 if (r < 0)
1136 return r;
1138 r = transient_aux_units_from_message(m, message, error);
1139 if (r < 0)
1140 return r;
1142 /* Finally, start it */
1143 return bus_unit_queue_job(message, u, JOB_START, mode, 0, error);
1146 static int method_get_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1147 _cleanup_free_ char *path = NULL;
1148 Manager *m = ASSERT_PTR(userdata);
1149 uint32_t id;
1150 Job *j;
1151 int r;
1153 assert(message);
1155 /* Anyone can call this method */
1157 r = sd_bus_message_read(message, "u", &id);
1158 if (r < 0)
1159 return r;
1161 j = manager_get_job(m, id);
1162 if (!j)
1163 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
1165 r = mac_selinux_unit_access_check(j->unit, message, "status", error);
1166 if (r < 0)
1167 return r;
1169 path = job_dbus_path(j);
1170 if (!path)
1171 return -ENOMEM;
1173 return sd_bus_reply_method_return(message, "o", path);
1176 static int method_cancel_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1177 Manager *m = ASSERT_PTR(userdata);
1178 uint32_t id;
1179 Job *j;
1180 int r;
1182 assert(message);
1184 r = sd_bus_message_read(message, "u", &id);
1185 if (r < 0)
1186 return r;
1188 j = manager_get_job(m, id);
1189 if (!j)
1190 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
1192 return bus_job_method_cancel(message, j, error);
1195 static int method_clear_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1196 Manager *m = ASSERT_PTR(userdata);
1197 int r;
1199 assert(message);
1201 r = mac_selinux_access_check(message, "reload", error);
1202 if (r < 0)
1203 return r;
1205 r = bus_verify_manage_units_async(m, message, error);
1206 if (r < 0)
1207 return r;
1208 if (r == 0)
1209 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1211 manager_clear_jobs(m);
1213 return sd_bus_reply_method_return(message, NULL);
1216 static int method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1217 Manager *m = ASSERT_PTR(userdata);
1218 int r;
1220 assert(message);
1222 r = mac_selinux_access_check(message, "reload", error);
1223 if (r < 0)
1224 return r;
1226 r = bus_verify_manage_units_async(m, message, error);
1227 if (r < 0)
1228 return r;
1229 if (r == 0)
1230 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1232 manager_reset_failed(m);
1234 return sd_bus_reply_method_return(message, NULL);
1237 static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
1238 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1239 Manager *m = ASSERT_PTR(userdata);
1240 const char *k;
1241 Unit *u;
1242 int r;
1244 assert(message);
1246 /* Anyone can call this method */
1248 r = mac_selinux_access_check(message, "status", error);
1249 if (r < 0)
1250 return r;
1252 r = sd_bus_message_new_method_return(message, &reply);
1253 if (r < 0)
1254 return r;
1256 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
1257 if (r < 0)
1258 return r;
1260 HASHMAP_FOREACH_KEY(u, k, m->units) {
1261 if (k != u->id)
1262 continue;
1264 if (!strv_isempty(states) &&
1265 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
1266 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
1267 !strv_contains(states, unit_sub_state_to_string(u)))
1268 continue;
1270 if (!strv_isempty(patterns) &&
1271 !strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
1272 continue;
1274 r = reply_unit_info(reply, u);
1275 if (r < 0)
1276 return r;
1279 r = sd_bus_message_close_container(reply);
1280 if (r < 0)
1281 return r;
1283 return sd_bus_send(NULL, reply, NULL);
1286 static int method_list_units(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1287 return list_units_filtered(message, userdata, error, NULL, NULL);
1290 static int method_list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1291 _cleanup_strv_free_ char **states = NULL;
1292 int r;
1294 r = sd_bus_message_read_strv(message, &states);
1295 if (r < 0)
1296 return r;
1298 return list_units_filtered(message, userdata, error, states, NULL);
1301 static int method_list_units_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1302 _cleanup_strv_free_ char **states = NULL;
1303 _cleanup_strv_free_ char **patterns = NULL;
1304 int r;
1306 r = sd_bus_message_read_strv(message, &states);
1307 if (r < 0)
1308 return r;
1310 r = sd_bus_message_read_strv(message, &patterns);
1311 if (r < 0)
1312 return r;
1314 return list_units_filtered(message, userdata, error, states, patterns);
1317 static int method_list_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1318 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1319 Manager *m = ASSERT_PTR(userdata);
1320 Job *j;
1321 int r;
1323 assert(message);
1325 /* Anyone can call this method */
1327 r = mac_selinux_access_check(message, "status", error);
1328 if (r < 0)
1329 return r;
1331 r = sd_bus_message_new_method_return(message, &reply);
1332 if (r < 0)
1333 return r;
1335 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
1336 if (r < 0)
1337 return r;
1339 HASHMAP_FOREACH(j, m->jobs) {
1340 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
1342 job_path = job_dbus_path(j);
1343 if (!job_path)
1344 return -ENOMEM;
1346 unit_path = unit_dbus_path(j->unit);
1347 if (!unit_path)
1348 return -ENOMEM;
1350 r = sd_bus_message_append(
1351 reply, "(usssoo)",
1352 j->id,
1353 j->unit->id,
1354 job_type_to_string(j->type),
1355 job_state_to_string(j->state),
1356 job_path,
1357 unit_path);
1358 if (r < 0)
1359 return r;
1362 r = sd_bus_message_close_container(reply);
1363 if (r < 0)
1364 return r;
1366 return sd_bus_send(NULL, reply, NULL);
1369 static int method_subscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1370 Manager *m = ASSERT_PTR(userdata);
1371 int r;
1373 assert(message);
1375 /* Anyone can call this method */
1377 r = mac_selinux_access_check(message, "status", error);
1378 if (r < 0)
1379 return r;
1381 if (sd_bus_message_get_bus(message) == m->api_bus) {
1383 /* Note that direct bus connection subscribe by
1384 * default, we only track peers on the API bus here */
1386 if (!m->subscribed) {
1387 r = sd_bus_track_new(sd_bus_message_get_bus(message), &m->subscribed, NULL, NULL);
1388 if (r < 0)
1389 return r;
1392 r = sd_bus_track_add_sender(m->subscribed, message);
1393 if (r < 0)
1394 return r;
1395 if (r == 0)
1396 return sd_bus_error_set(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1399 return sd_bus_reply_method_return(message, NULL);
1402 static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1403 Manager *m = ASSERT_PTR(userdata);
1404 int r;
1406 assert(message);
1408 /* Anyone can call this method */
1410 r = mac_selinux_access_check(message, "status", error);
1411 if (r < 0)
1412 return r;
1414 if (sd_bus_message_get_bus(message) == m->api_bus) {
1415 r = sd_bus_track_remove_sender(m->subscribed, message);
1416 if (r < 0)
1417 return r;
1418 if (r == 0)
1419 return sd_bus_error_set(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1422 return sd_bus_reply_method_return(message, NULL);
1425 static int dump_impl(
1426 sd_bus_message *message,
1427 void *userdata,
1428 sd_bus_error *error,
1429 char **patterns,
1430 int (*reply)(sd_bus_message *, char *)) {
1432 _cleanup_free_ char *dump = NULL;
1433 Manager *m = ASSERT_PTR(userdata);
1434 int r;
1436 assert(message);
1438 /* 'status' access is the bare minimum always needed for this, as the policy might straight out
1439 * forbid a client from querying any information from systemd, regardless of any rate limiting. */
1440 r = mac_selinux_access_check(message, "status", error);
1441 if (r < 0)
1442 return r;
1444 /* Rate limit reached? Check if the caller is privileged/allowed by policy to bypass this. We
1445 * check the rate limit first to avoid the expensive roundtrip to polkit when not needed. */
1446 if (!ratelimit_below(&m->dump_ratelimit)) {
1447 /* We need a way for SELinux to constrain the operation when the rate limit is active, even
1448 * if polkit would allow it, but we cannot easily add new named permissions, so we need to
1449 * use an existing one. Reload/reexec are also slow but non-destructive/modifying
1450 * operations, and can cause PID1 to stall. So it seems similar enough in terms of security
1451 * considerations and impact, and thus use the same access check for dumps which, given the
1452 * large amount of data to fetch, can stall PID1 for quite some time. */
1453 r = mac_selinux_access_check(message, "reload", error);
1454 if (r < 0)
1455 goto ratelimited;
1457 r = bus_verify_bypass_dump_ratelimit_async(m, message, error);
1458 if (r < 0)
1459 goto ratelimited;
1460 if (r == 0)
1461 /* No authorization for now, but the async polkit stuff will call us again when it
1462 * has it */
1463 return 1;
1466 r = manager_get_dump_string(m, patterns, &dump);
1467 if (r < 0)
1468 return r;
1470 return reply(message, dump);
1472 ratelimited:
1473 log_warning("Dump request rejected due to rate limit on unprivileged callers, blocked for %s.",
1474 FORMAT_TIMESPAN(ratelimit_left(&m->dump_ratelimit), USEC_PER_SEC));
1475 return sd_bus_error_setf(error,
1476 SD_BUS_ERROR_LIMITS_EXCEEDED,
1477 "Dump request rejected due to rate limit on unprivileged callers, blocked for %s.",
1478 FORMAT_TIMESPAN(ratelimit_left(&m->dump_ratelimit), USEC_PER_SEC));
1481 static int reply_dump(sd_bus_message *message, char *dump) {
1482 return sd_bus_reply_method_return(message, "s", dump);
1485 static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1486 return dump_impl(message, userdata, error, NULL, reply_dump);
1489 static int reply_dump_by_fd(sd_bus_message *message, char *dump) {
1490 _cleanup_close_ int fd = -EBADF;
1492 fd = acquire_data_fd(dump, strlen(dump), 0);
1493 if (fd < 0)
1494 return fd;
1496 return sd_bus_reply_method_return(message, "h", fd);
1499 static int method_dump_by_fd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1500 return dump_impl(message, userdata, error, NULL, reply_dump_by_fd);
1503 static int dump_units_matching_patterns(
1504 sd_bus_message *message,
1505 void *userdata,
1506 sd_bus_error *error,
1507 int (*reply)(sd_bus_message *, char *)) {
1508 _cleanup_strv_free_ char **patterns = NULL;
1509 int r;
1511 r = sd_bus_message_read_strv(message, &patterns);
1512 if (r < 0)
1513 return r;
1515 return dump_impl(message, userdata, error, patterns, reply);
1518 static int method_dump_units_matching_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1519 return dump_units_matching_patterns(message, userdata, error, reply_dump);
1522 static int method_dump_units_matching_patterns_by_fd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1523 return dump_units_matching_patterns(message, userdata, error, reply_dump_by_fd);
1526 static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1527 return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
1530 static int get_run_space(uint64_t *ret, sd_bus_error *error) {
1531 struct statvfs svfs;
1533 assert(ret);
1535 if (statvfs("/run/systemd", &svfs) < 0)
1536 return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m");
1538 *ret = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
1539 return 0;
1542 static int verify_run_space(const char *message, sd_bus_error *error) {
1543 uint64_t available = 0; /* unnecessary, but used to trick out gcc's incorrect maybe-uninitialized warning */
1544 int r;
1546 assert(message);
1548 r = get_run_space(&available, error);
1549 if (r < 0)
1550 return r;
1552 if (available < RELOAD_DISK_SPACE_MIN)
1553 return sd_bus_error_setf(error,
1554 BUS_ERROR_DISK_FULL,
1555 "%s, not enough space available on /run/systemd/. "
1556 "Currently, %s are free, but a safety buffer of %s is enforced.",
1557 message,
1558 FORMAT_BYTES(available),
1559 FORMAT_BYTES(RELOAD_DISK_SPACE_MIN));
1561 return 0;
1564 int verify_run_space_and_log(const char *message) {
1565 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1566 int r;
1568 assert(message);
1570 r = verify_run_space(message, &error);
1571 if (r < 0)
1572 return log_error_errno(r, "%s", bus_error_message(&error, r));
1574 return 0;
1577 static int verify_run_space_permissive(const char *message, sd_bus_error *error) {
1578 uint64_t available = 0; /* unnecessary, but used to trick out gcc's incorrect maybe-uninitialized warning */
1579 int r;
1581 assert(message);
1583 r = get_run_space(&available, error);
1584 if (r < 0)
1585 return r;
1587 if (available < RELOAD_DISK_SPACE_MIN)
1588 log_warning("Dangerously low amount of free space on /run/systemd/, %s.\n"
1589 "Currently, %s are free, but %s are suggested. Proceeding anyway.",
1590 message,
1591 FORMAT_BYTES(available),
1592 FORMAT_BYTES(RELOAD_DISK_SPACE_MIN));
1594 return 0;
1597 static void log_caller(sd_bus_message *message, Manager *manager, const char *method) {
1598 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1599 const char *comm = NULL;
1600 Unit *caller;
1601 pid_t pid;
1603 assert(message);
1604 assert(manager);
1605 assert(method);
1607 if (sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID|SD_BUS_CREDS_AUGMENT|SD_BUS_CREDS_COMM, &creds) < 0)
1608 return;
1610 /* We need at least the PID, otherwise there's nothing to log, the rest is optional */
1611 if (sd_bus_creds_get_pid(creds, &pid) < 0)
1612 return;
1614 (void) sd_bus_creds_get_comm(creds, &comm);
1615 caller = manager_get_unit_by_pid(manager, pid);
1617 log_info("%s requested from client PID " PID_FMT "%s%s%s%s%s%s...",
1618 method, pid,
1619 comm ? " ('" : "", strempty(comm), comm ? "')" : "",
1620 caller ? " (unit " : "", caller ? caller->id : "", caller ? ")" : "");
1623 static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1624 Manager *m = ASSERT_PTR(userdata);
1625 int r;
1627 assert(message);
1629 r = verify_run_space("Refusing to reload", error);
1630 if (r < 0)
1631 return r;
1633 r = mac_selinux_access_check(message, "reload", error);
1634 if (r < 0)
1635 return r;
1637 r = bus_verify_reload_daemon_async(m, message, error);
1638 if (r < 0)
1639 return r;
1640 if (r == 0)
1641 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1643 /* Write a log message noting the unit or process who requested the Reload() */
1644 log_caller(message, m, "Reloading");
1646 /* Check the rate limit after the authorization succeeds, to avoid denial-of-service issues. */
1647 if (!ratelimit_below(&m->reload_ratelimit)) {
1648 log_warning("Reloading request rejected due to rate limit.");
1649 return sd_bus_error_setf(error,
1650 SD_BUS_ERROR_LIMITS_EXCEEDED,
1651 "Reload() request rejected due to rate limit.");
1654 /* Instead of sending the reply back right away, we just
1655 * remember that we need to and then send it after the reload
1656 * is finished. That way the caller knows when the reload
1657 * finished. */
1659 assert(!m->pending_reload_message);
1660 r = sd_bus_message_new_method_return(message, &m->pending_reload_message);
1661 if (r < 0)
1662 return r;
1664 m->objective = MANAGER_RELOAD;
1666 return 1;
1669 static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1670 Manager *m = ASSERT_PTR(userdata);
1671 int r;
1673 assert(message);
1675 r = verify_run_space("Refusing to reexecute", error);
1676 if (r < 0)
1677 return r;
1679 r = mac_selinux_access_check(message, "reload", error);
1680 if (r < 0)
1681 return r;
1683 r = bus_verify_reload_daemon_async(m, message, error);
1684 if (r < 0)
1685 return r;
1686 if (r == 0)
1687 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1689 /* Write a log message noting the unit or process who requested the Reexecute() */
1690 log_caller(message, m, "Reexecuting");
1692 /* We don't send a reply back here, the client should
1693 * just wait for us disconnecting. */
1695 m->objective = MANAGER_REEXECUTE;
1696 return 1;
1699 static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1700 Manager *m = ASSERT_PTR(userdata);
1701 int r;
1703 assert(message);
1705 r = mac_selinux_access_check(message, "halt", error);
1706 if (r < 0)
1707 return r;
1709 /* Exit() (in contrast to SetExitCode()) is actually allowed even if
1710 * we are running on the host. It will fall back on reboot() in
1711 * systemd-shutdown if it cannot do the exit() because it isn't a
1712 * container. */
1714 m->objective = MANAGER_EXIT;
1716 return sd_bus_reply_method_return(message, NULL);
1719 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1720 Manager *m = ASSERT_PTR(userdata);
1721 int r;
1723 assert(message);
1725 r = mac_selinux_access_check(message, "reboot", error);
1726 if (r < 0)
1727 return r;
1729 if (!MANAGER_IS_SYSTEM(m))
1730 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
1731 "Reboot is only supported for system managers.");
1733 m->objective = MANAGER_REBOOT;
1735 return sd_bus_reply_method_return(message, NULL);
1738 static int method_soft_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1739 _cleanup_free_ char *rt = NULL;
1740 Manager *m = ASSERT_PTR(userdata);
1741 const char *root;
1742 int r;
1744 assert(message);
1746 r = verify_run_space_permissive("soft reboot may fail", error);
1747 if (r < 0)
1748 return r;
1750 r = mac_selinux_access_check(message, "reboot", error);
1751 if (r < 0)
1752 return r;
1754 r = sd_bus_message_read(message, "s", &root);
1755 if (r < 0)
1756 return r;
1758 if (!isempty(root)) {
1759 if (!path_is_valid(root))
1760 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1761 "New root directory '%s' must be a valid path.", root);
1762 if (!path_is_absolute(root))
1763 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1764 "New root directory path '%s' is not absolute.", root);
1766 rt = strdup(root);
1767 if (!rt)
1768 return -ENOMEM;
1771 free_and_replace(m->switch_root, rt);
1772 m->objective = MANAGER_SOFT_REBOOT;
1774 return sd_bus_reply_method_return(message, NULL);
1777 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1778 Manager *m = ASSERT_PTR(userdata);
1779 int r;
1781 assert(message);
1783 r = mac_selinux_access_check(message, "halt", error);
1784 if (r < 0)
1785 return r;
1787 if (!MANAGER_IS_SYSTEM(m))
1788 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
1789 "Powering off is only supported for system managers.");
1791 m->objective = MANAGER_POWEROFF;
1793 return sd_bus_reply_method_return(message, NULL);
1796 static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1797 Manager *m = ASSERT_PTR(userdata);
1798 int r;
1800 assert(message);
1802 r = mac_selinux_access_check(message, "halt", error);
1803 if (r < 0)
1804 return r;
1806 if (!MANAGER_IS_SYSTEM(m))
1807 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
1808 "Halt is only supported for system managers.");
1810 m->objective = MANAGER_HALT;
1812 return sd_bus_reply_method_return(message, NULL);
1815 static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1816 Manager *m = ASSERT_PTR(userdata);
1817 int r;
1819 assert(message);
1821 r = mac_selinux_access_check(message, "reboot", error);
1822 if (r < 0)
1823 return r;
1825 if (!MANAGER_IS_SYSTEM(m))
1826 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
1827 "KExec is only supported for system managers.");
1829 m->objective = MANAGER_KEXEC;
1831 return sd_bus_reply_method_return(message, NULL);
1834 static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1835 _cleanup_free_ char *ri = NULL, *rt = NULL;
1836 Manager *m = ASSERT_PTR(userdata);
1837 const char *root, *init;
1838 int r;
1840 assert(message);
1842 r = verify_run_space_permissive("root switching may fail", error);
1843 if (r < 0)
1844 return r;
1846 r = mac_selinux_access_check(message, "reboot", error);
1847 if (r < 0)
1848 return r;
1850 if (!MANAGER_IS_SYSTEM(m))
1851 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
1852 "Root switching is only supported by system manager.");
1854 r = sd_bus_message_read(message, "ss", &root, &init);
1855 if (r < 0)
1856 return r;
1858 if (isempty(root))
1859 /* If path is not specified, default to "/sysroot" which is what we generally expect initrds
1860 * to use */
1861 root = "/sysroot";
1862 else {
1863 if (!path_is_valid(root))
1864 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1865 "New root directory must be a valid path.");
1866 if (!path_is_absolute(root))
1867 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1868 "New root path '%s' is not absolute.", root);
1869 if (path_equal(root, "/"))
1870 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1871 "New root directory cannot be the old root directory.");
1874 /* Safety check */
1875 if (isempty(init)) {
1876 r = path_is_os_tree(root);
1877 if (r < 0)
1878 return sd_bus_error_set_errnof(error, r,
1879 "Failed to determine whether root path '%s' contains an OS tree: %m",
1880 root);
1881 if (r == 0)
1882 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1883 "Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.",
1884 root);
1885 } else {
1886 if (!path_is_valid(init))
1887 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1888 "Path to init binary '%s' is not a valid path.", init);
1890 if (!path_is_absolute(init))
1891 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1892 "Path to init binary '%s' not absolute.", init);
1894 r = chase_and_access(init, root, CHASE_PREFIX_ROOT, X_OK, NULL);
1895 if (r == -EACCES)
1896 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1897 "Init binary %s is not executable.", init);
1898 if (r < 0)
1899 return sd_bus_error_set_errnof(error, r,
1900 "Could not resolve init executable %s: %m", init);
1903 rt = strdup(root);
1904 if (!rt)
1905 return -ENOMEM;
1907 if (!isempty(init)) {
1908 ri = strdup(init);
1909 if (!ri)
1910 return -ENOMEM;
1913 free_and_replace(m->switch_root, rt);
1914 free_and_replace(m->switch_root_init, ri);
1916 m->objective = MANAGER_SWITCH_ROOT;
1918 return sd_bus_reply_method_return(message, NULL);
1921 static int method_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1922 _cleanup_strv_free_ char **plus = NULL;
1923 Manager *m = ASSERT_PTR(userdata);
1924 int r;
1926 assert(message);
1928 r = mac_selinux_access_check(message, "reload", error);
1929 if (r < 0)
1930 return r;
1932 r = sd_bus_message_read_strv(message, &plus);
1933 if (r < 0)
1934 return r;
1935 if (!strv_env_is_valid(plus))
1936 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1938 r = bus_verify_set_environment_async(m, message, error);
1939 if (r < 0)
1940 return r;
1941 if (r == 0)
1942 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1944 r = manager_client_environment_modify(m, NULL, plus);
1945 if (r < 0)
1946 return r;
1948 return sd_bus_reply_method_return(message, NULL);
1951 static int method_unset_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1952 _cleanup_strv_free_ char **minus = NULL;
1953 Manager *m = ASSERT_PTR(userdata);
1954 int r;
1956 assert(message);
1958 r = mac_selinux_access_check(message, "reload", error);
1959 if (r < 0)
1960 return r;
1962 r = sd_bus_message_read_strv(message, &minus);
1963 if (r < 0)
1964 return r;
1966 if (!strv_env_name_or_assignment_is_valid(minus))
1967 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1968 "Invalid environment variable names or assignments");
1970 r = bus_verify_set_environment_async(m, message, error);
1971 if (r < 0)
1972 return r;
1973 if (r == 0)
1974 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1976 r = manager_client_environment_modify(m, minus, NULL);
1977 if (r < 0)
1978 return r;
1980 return sd_bus_reply_method_return(message, NULL);
1983 static int method_unset_and_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1984 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1985 Manager *m = ASSERT_PTR(userdata);
1986 int r;
1988 assert(message);
1990 r = mac_selinux_access_check(message, "reload", error);
1991 if (r < 0)
1992 return r;
1994 r = sd_bus_message_read_strv(message, &minus);
1995 if (r < 0)
1996 return r;
1998 r = sd_bus_message_read_strv(message, &plus);
1999 if (r < 0)
2000 return r;
2002 if (!strv_env_name_or_assignment_is_valid(minus))
2003 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
2004 "Invalid environment variable names or assignments");
2005 if (!strv_env_is_valid(plus))
2006 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
2007 "Invalid environment assignments");
2009 r = bus_verify_set_environment_async(m, message, error);
2010 if (r < 0)
2011 return r;
2012 if (r == 0)
2013 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2015 r = manager_client_environment_modify(m, minus, plus);
2016 if (r < 0)
2017 return r;
2019 return sd_bus_reply_method_return(message, NULL);
2022 static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2023 Manager *m = ASSERT_PTR(userdata);
2024 uint8_t code;
2025 int r;
2027 assert(message);
2029 r = mac_selinux_access_check(message, "exit", error);
2030 if (r < 0)
2031 return r;
2033 r = sd_bus_message_read_basic(message, 'y', &code);
2034 if (r < 0)
2035 return r;
2037 m->return_value = code;
2039 return sd_bus_reply_method_return(message, NULL);
2042 static int method_lookup_dynamic_user_by_name(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2043 Manager *m = ASSERT_PTR(userdata);
2044 const char *name;
2045 uid_t uid;
2046 int r;
2048 assert(message);
2050 r = sd_bus_message_read_basic(message, 's', &name);
2051 if (r < 0)
2052 return r;
2054 if (!MANAGER_IS_SYSTEM(m))
2055 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
2056 "Dynamic users are only supported in the system instance.");
2057 if (!valid_user_group_name(name, VALID_USER_RELAX))
2058 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
2059 "User name invalid: %s", name);
2061 r = dynamic_user_lookup_name(m, name, &uid);
2062 if (r == -ESRCH)
2063 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER,
2064 "Dynamic user %s does not exist.", name);
2065 if (r < 0)
2066 return r;
2068 return sd_bus_reply_method_return(message, "u", (uint32_t) uid);
2071 static int method_lookup_dynamic_user_by_uid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2072 _cleanup_free_ char *name = NULL;
2073 Manager *m = ASSERT_PTR(userdata);
2074 uid_t uid;
2075 int r;
2077 assert(message);
2079 assert_cc(sizeof(uid_t) == sizeof(uint32_t));
2080 r = sd_bus_message_read_basic(message, 'u', &uid);
2081 if (r < 0)
2082 return r;
2084 if (!MANAGER_IS_SYSTEM(m))
2085 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
2086 "Dynamic users are only supported in the system instance.");
2087 if (!uid_is_valid(uid))
2088 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
2089 "User ID invalid: " UID_FMT, uid);
2091 r = dynamic_user_lookup_uid(m, uid, &name);
2092 if (r == -ESRCH)
2093 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER,
2094 "Dynamic user ID " UID_FMT " does not exist.", uid);
2095 if (r < 0)
2096 return r;
2098 return sd_bus_reply_method_return(message, "s", name);
2101 static int method_get_dynamic_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2102 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2103 Manager *m = ASSERT_PTR(userdata);
2104 DynamicUser *d;
2105 int r;
2107 assert(message);
2109 assert_cc(sizeof(uid_t) == sizeof(uint32_t));
2111 if (!MANAGER_IS_SYSTEM(m))
2112 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED,
2113 "Dynamic users are only supported in the system instance.");
2115 r = sd_bus_message_new_method_return(message, &reply);
2116 if (r < 0)
2117 return r;
2119 r = sd_bus_message_open_container(reply, 'a', "(us)");
2120 if (r < 0)
2121 return r;
2123 HASHMAP_FOREACH(d, m->dynamic_users) {
2124 uid_t uid;
2126 r = dynamic_user_current(d, &uid);
2127 if (r == -EAGAIN) /* not realized yet? */
2128 continue;
2129 if (r < 0)
2130 return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED,
2131 "Failed to look up a dynamic user.");
2133 r = sd_bus_message_append(reply, "(us)", uid, d->name);
2134 if (r < 0)
2135 return r;
2138 r = sd_bus_message_close_container(reply);
2139 if (r < 0)
2140 return r;
2142 return sd_bus_send(NULL, reply, NULL);
2145 static int method_enqueue_marked_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2146 Manager *m = ASSERT_PTR(userdata);
2147 int r;
2149 assert(message);
2151 r = mac_selinux_access_check(message, "start", error);
2152 if (r < 0)
2153 return r;
2155 r = bus_verify_manage_units_async(m, message, error);
2156 if (r < 0)
2157 return r;
2158 if (r == 0)
2159 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2161 log_info("Queuing reload/restart jobs for marked units%s", special_glyph(SPECIAL_GLYPH_ELLIPSIS));
2163 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2164 r = sd_bus_message_new_method_return(message, &reply);
2165 if (r < 0)
2166 return r;
2168 r = sd_bus_message_open_container(reply, 'a', "o");
2169 if (r < 0)
2170 return r;
2172 Unit *u;
2173 char *k;
2174 int ret = 0;
2175 HASHMAP_FOREACH_KEY(u, k, m->units) {
2176 /* ignore aliases */
2177 if (u->id != k)
2178 continue;
2180 BusUnitQueueFlags flags;
2181 if (FLAGS_SET(u->markers, 1u << UNIT_MARKER_NEEDS_RESTART))
2182 flags = 0;
2183 else if (FLAGS_SET(u->markers, 1u << UNIT_MARKER_NEEDS_RELOAD))
2184 flags = BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE;
2185 else
2186 continue;
2188 r = mac_selinux_unit_access_check(u, message, "start", error);
2189 if (r >= 0)
2190 r = bus_unit_queue_job_one(message, u,
2191 JOB_TRY_RESTART, JOB_FAIL, flags,
2192 reply, error);
2193 if (r < 0) {
2194 if (ERRNO_IS_RESOURCE(r))
2195 return r;
2196 if (ret >= 0)
2197 ret = r;
2198 sd_bus_error_free(error);
2202 if (ret < 0)
2203 return sd_bus_error_set_errnof(error, ret,
2204 "Failed to enqueue some jobs, see logs for details: %m");
2206 r = sd_bus_message_close_container(reply);
2207 if (r < 0)
2208 return r;
2210 return sd_bus_send(NULL, reply, NULL);
2213 static int list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
2214 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2215 Manager *m = ASSERT_PTR(userdata);
2216 UnitFileList *item;
2217 _cleanup_hashmap_free_ Hashmap *h = NULL;
2218 int r;
2220 assert(message);
2222 /* Anyone can call this method */
2224 r = mac_selinux_access_check(message, "status", error);
2225 if (r < 0)
2226 return r;
2228 r = sd_bus_message_new_method_return(message, &reply);
2229 if (r < 0)
2230 return r;
2232 h = hashmap_new(&unit_file_list_hash_ops_free);
2233 if (!h)
2234 return -ENOMEM;
2236 r = unit_file_get_list(m->runtime_scope, NULL, h, states, patterns);
2237 if (r < 0)
2238 return r;
2240 r = sd_bus_message_open_container(reply, 'a', "(ss)");
2241 if (r < 0)
2242 return r;
2244 HASHMAP_FOREACH(item, h) {
2246 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
2247 if (r < 0)
2248 return r;
2251 r = sd_bus_message_close_container(reply);
2252 if (r < 0)
2253 return r;
2255 return sd_bus_send(NULL, reply, NULL);
2258 static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2259 return list_unit_files_by_patterns(message, userdata, error, NULL, NULL);
2262 static int method_list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2263 _cleanup_strv_free_ char **states = NULL;
2264 _cleanup_strv_free_ char **patterns = NULL;
2265 int r;
2267 r = sd_bus_message_read_strv(message, &states);
2268 if (r < 0)
2269 return r;
2271 r = sd_bus_message_read_strv(message, &patterns);
2272 if (r < 0)
2273 return r;
2275 return list_unit_files_by_patterns(message, userdata, error, states, patterns);
2278 static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2279 Manager *m = ASSERT_PTR(userdata);
2280 const char *name;
2281 UnitFileState state;
2282 int r;
2284 assert(message);
2286 /* Anyone can call this method */
2288 r = mac_selinux_access_check(message, "status", error);
2289 if (r < 0)
2290 return r;
2292 r = sd_bus_message_read(message, "s", &name);
2293 if (r < 0)
2294 return r;
2296 r = unit_file_get_state(m->runtime_scope, NULL, name, &state);
2297 if (r < 0)
2298 return r;
2300 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
2303 static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2304 _cleanup_free_ char *default_target = NULL;
2305 Manager *m = ASSERT_PTR(userdata);
2306 int r;
2308 assert(message);
2310 /* Anyone can call this method */
2312 r = mac_selinux_access_check(message, "status", error);
2313 if (r < 0)
2314 return r;
2316 r = unit_file_get_default(m->runtime_scope, NULL, &default_target);
2317 if (r == -ERFKILL)
2318 sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked.");
2319 if (r < 0)
2320 return r;
2322 return sd_bus_reply_method_return(message, "s", default_target);
2325 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
2326 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
2327 int r;
2329 assert(bus);
2331 r = sd_bus_message_new_signal(bus, &message,
2332 "/org/freedesktop/systemd1",
2333 "org.freedesktop.systemd1.Manager",
2334 "UnitFilesChanged");
2335 if (r < 0)
2336 return r;
2338 return sd_bus_send(bus, message, NULL);
2341 /* Create an error reply, using the error information from changes[]
2342 * if possible, and fall back to generating an error from error code c.
2343 * The error message only describes the first error.
2345 static int install_error(
2346 sd_bus_error *error,
2347 int c,
2348 InstallChange *changes,
2349 size_t n_changes) {
2351 CLEANUP_ARRAY(changes, n_changes, install_changes_free);
2353 for (size_t i = 0; i < n_changes; i++)
2355 /* When making changes here, make sure to also change install_changes_dump() in install.c. */
2357 switch (changes[i].type) {
2358 case 0 ... _INSTALL_CHANGE_TYPE_MAX: /* not errors */
2359 break;
2361 case -EEXIST:
2362 if (changes[i].source)
2363 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
2364 "File %s already exists and is a symlink to %s.",
2365 changes[i].path, changes[i].source);
2366 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
2367 "File %s already exists.",
2368 changes[i].path);
2370 case -ERFKILL:
2371 return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED,
2372 "Unit file %s is masked.", changes[i].path);
2374 case -EADDRNOTAVAIL:
2375 return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED,
2376 "Unit %s is transient or generated.", changes[i].path);
2378 case -ETXTBSY:
2379 return sd_bus_error_setf(error, BUS_ERROR_UNIT_BAD_PATH,
2380 "File %s is under the systemd unit hierarchy already.", changes[i].path);
2382 case -EBADSLT:
2383 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING,
2384 "Invalid specifier in %s.", changes[i].path);
2386 case -EIDRM:
2387 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING,
2388 "Destination unit %s is a non-template unit.", changes[i].path);
2390 case -EUCLEAN:
2391 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING,
2392 "\"%s\" is not a valid unit name.",
2393 changes[i].path);
2395 case -ELOOP:
2396 return sd_bus_error_setf(error, BUS_ERROR_UNIT_LINKED,
2397 "Refusing to operate on alias name or linked unit file: %s",
2398 changes[i].path);
2400 case -EXDEV:
2401 if (changes[i].source)
2402 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING,
2403 "Cannot alias %s as %s.",
2404 changes[i].source, changes[i].path);
2405 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING,
2406 "Invalid unit reference %s.", changes[i].path);
2408 case -ENOENT:
2409 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT,
2410 "Unit file %s does not exist.", changes[i].path);
2412 case -EUNATCH:
2413 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING,
2414 "Cannot resolve specifiers in %s.", changes[i].path);
2416 default:
2417 assert(changes[i].type < 0); /* other errors */
2418 return sd_bus_error_set_errnof(error, changes[i].type, "File %s: %m", changes[i].path);
2421 return c < 0 ? c : -EINVAL;
2424 static int reply_install_changes_and_free(
2425 Manager *m,
2426 sd_bus_message *message,
2427 int carries_install_info,
2428 InstallChange *changes,
2429 size_t n_changes,
2430 sd_bus_error *error) {
2432 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2433 bool bad = false, good = false;
2434 int r;
2436 CLEANUP_ARRAY(changes, n_changes, install_changes_free);
2438 if (install_changes_have_modification(changes, n_changes)) {
2439 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
2440 if (r < 0)
2441 log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
2444 r = sd_bus_message_new_method_return(message, &reply);
2445 if (r < 0)
2446 return r;
2448 if (carries_install_info >= 0) {
2449 r = sd_bus_message_append(reply, "b", carries_install_info);
2450 if (r < 0)
2451 return r;
2454 r = sd_bus_message_open_container(reply, 'a', "(sss)");
2455 if (r < 0)
2456 return r;
2458 for (size_t i = 0; i < n_changes; i++) {
2460 if (changes[i].type < 0) {
2461 bad = true;
2462 continue;
2465 r = sd_bus_message_append(
2466 reply, "(sss)",
2467 install_change_type_to_string(changes[i].type),
2468 changes[i].path,
2469 changes[i].source);
2470 if (r < 0)
2471 return r;
2473 good = true;
2476 /* If there was a failed change, and no successful change, then return the first failure as proper
2477 * method call error. */
2478 if (bad && !good)
2479 return install_error(error, 0, TAKE_PTR(changes), n_changes);
2481 r = sd_bus_message_close_container(reply);
2482 if (r < 0)
2483 return r;
2485 return sd_bus_send(NULL, reply, NULL);
2488 static int method_enable_unit_files_generic(
2489 sd_bus_message *message,
2490 Manager *m,
2491 int (*call)(RuntimeScope scope, UnitFileFlags flags, const char *root_dir, char *files[], InstallChange **changes, size_t *n_changes),
2492 bool carries_install_info,
2493 sd_bus_error *error) {
2495 _cleanup_strv_free_ char **l = NULL;
2496 InstallChange *changes = NULL;
2497 size_t n_changes = 0;
2498 UnitFileFlags flags;
2499 int r;
2501 assert(message);
2502 assert(m);
2504 r = sd_bus_message_read_strv(message, &l);
2505 if (r < 0)
2506 return r;
2508 if (sd_bus_message_is_method_call(message, NULL, "EnableUnitFilesWithFlags")) {
2509 uint64_t raw_flags;
2511 r = sd_bus_message_read(message, "t", &raw_flags);
2512 if (r < 0)
2513 return r;
2514 if ((raw_flags & ~_UNIT_FILE_FLAGS_MASK_PUBLIC) != 0)
2515 return -EINVAL;
2516 flags = raw_flags;
2517 } else {
2518 int runtime, force;
2520 r = sd_bus_message_read(message, "bb", &runtime, &force);
2521 if (r < 0)
2522 return r;
2523 flags = unit_file_bools_to_flags(runtime, force);
2526 r = bus_verify_manage_unit_files_async(m, message, error);
2527 if (r < 0)
2528 return r;
2529 if (r == 0)
2530 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2532 r = call(m->runtime_scope, flags, NULL, l, &changes, &n_changes);
2533 if (r < 0)
2534 return install_error(error, r, changes, n_changes);
2536 return reply_install_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error);
2539 static int method_enable_unit_files_with_flags(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2540 return method_enable_unit_files_generic(message, userdata, unit_file_enable, /* carries_install_info = */ true, error);
2543 static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2544 return method_enable_unit_files_generic(message, userdata, unit_file_enable, /* carries_install_info = */ true, error);
2547 static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2548 return method_enable_unit_files_generic(message, userdata, unit_file_reenable, /* carries_install_info = */ true, error);
2551 static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2552 return method_enable_unit_files_generic(message, userdata, unit_file_link, /* carries_install_info = */ false, error);
2555 static int unit_file_preset_without_mode(RuntimeScope scope, UnitFileFlags flags, const char *root_dir, char **files, InstallChange **changes, size_t *n_changes) {
2556 return unit_file_preset(scope, flags, root_dir, files, UNIT_FILE_PRESET_FULL, changes, n_changes);
2559 static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2560 return method_enable_unit_files_generic(message, userdata, unit_file_preset_without_mode, /* carries_install_info = */ true, error);
2563 static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2564 return method_enable_unit_files_generic(message, userdata, unit_file_mask, /* carries_install_info = */ false, error);
2567 static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2569 _cleanup_strv_free_ char **l = NULL;
2570 InstallChange *changes = NULL;
2571 size_t n_changes = 0;
2572 Manager *m = ASSERT_PTR(userdata);
2573 UnitFilePresetMode preset_mode;
2574 int runtime, force, r;
2575 UnitFileFlags flags;
2576 const char *mode;
2578 assert(message);
2580 r = sd_bus_message_read_strv(message, &l);
2581 if (r < 0)
2582 return r;
2584 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
2585 if (r < 0)
2586 return r;
2588 flags = unit_file_bools_to_flags(runtime, force);
2590 if (isempty(mode))
2591 preset_mode = UNIT_FILE_PRESET_FULL;
2592 else {
2593 preset_mode = unit_file_preset_mode_from_string(mode);
2594 if (preset_mode < 0)
2595 return -EINVAL;
2598 r = bus_verify_manage_unit_files_async(m, message, error);
2599 if (r < 0)
2600 return r;
2601 if (r == 0)
2602 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2604 r = unit_file_preset(m->runtime_scope, flags, NULL, l, preset_mode, &changes, &n_changes);
2605 if (r < 0)
2606 return install_error(error, r, changes, n_changes);
2608 return reply_install_changes_and_free(m, message, r, changes, n_changes, error);
2611 static int method_disable_unit_files_generic(
2612 sd_bus_message *message,
2613 Manager *m,
2614 int (*call)(RuntimeScope scope, UnitFileFlags flags, const char *root_dir, char *files[], InstallChange **changes, size_t *n_changes),
2615 bool carries_install_info,
2616 sd_bus_error *error) {
2618 _cleanup_strv_free_ char **l = NULL;
2619 InstallChange *changes = NULL;
2620 UnitFileFlags flags;
2621 size_t n_changes = 0;
2622 int r;
2624 assert(message);
2625 assert(m);
2627 r = sd_bus_message_read_strv(message, &l);
2628 if (r < 0)
2629 return r;
2631 if (sd_bus_message_is_method_call(message, NULL, "DisableUnitFilesWithFlags") ||
2632 sd_bus_message_is_method_call(message, NULL, "DisableUnitFilesWithFlagsAndInstallInfo")) {
2633 uint64_t raw_flags;
2635 r = sd_bus_message_read(message, "t", &raw_flags);
2636 if (r < 0)
2637 return r;
2638 if ((raw_flags & ~_UNIT_FILE_FLAGS_MASK_PUBLIC) != 0 ||
2639 FLAGS_SET(raw_flags, UNIT_FILE_FORCE))
2640 return -EINVAL;
2641 flags = raw_flags;
2642 } else {
2643 int runtime;
2645 r = sd_bus_message_read(message, "b", &runtime);
2646 if (r < 0)
2647 return r;
2648 flags = unit_file_bools_to_flags(runtime, false);
2651 r = bus_verify_manage_unit_files_async(m, message, error);
2652 if (r < 0)
2653 return r;
2654 if (r == 0)
2655 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2657 r = call(m->runtime_scope, flags, NULL, l, &changes, &n_changes);
2658 if (r < 0)
2659 return install_error(error, r, changes, n_changes);
2661 return reply_install_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error);
2664 static int method_disable_unit_files_with_flags(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2665 return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ false, error);
2668 static int method_disable_unit_files_with_flags_and_install_info(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2669 return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ true, error);
2672 static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2673 return method_disable_unit_files_generic(message, userdata, unit_file_disable, /* carries_install_info = */ false, error);
2676 static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2677 return method_disable_unit_files_generic(message, userdata, unit_file_unmask, /* carries_install_info = */ false, error);
2680 static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2681 _cleanup_strv_free_ char **l = NULL;
2682 InstallChange *changes = NULL;
2683 size_t n_changes = 0;
2684 Manager *m = ASSERT_PTR(userdata);
2685 int r;
2687 assert(message);
2689 r = sd_bus_message_read_strv(message, &l);
2690 if (r < 0)
2691 return r;
2693 r = bus_verify_manage_unit_files_async(m, message, error);
2694 if (r < 0)
2695 return r;
2696 if (r == 0)
2697 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2699 r = unit_file_revert(m->runtime_scope, NULL, l, &changes, &n_changes);
2700 if (r < 0)
2701 return install_error(error, r, changes, n_changes);
2703 return reply_install_changes_and_free(m, message, -1, changes, n_changes, error);
2706 static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2707 InstallChange *changes = NULL;
2708 size_t n_changes = 0;
2709 Manager *m = ASSERT_PTR(userdata);
2710 const char *name;
2711 int force, r;
2713 assert(message);
2715 r = mac_selinux_access_check(message, "enable", error);
2716 if (r < 0)
2717 return r;
2719 r = sd_bus_message_read(message, "sb", &name, &force);
2720 if (r < 0)
2721 return r;
2723 r = bus_verify_manage_unit_files_async(m, message, error);
2724 if (r < 0)
2725 return r;
2726 if (r == 0)
2727 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2729 r = unit_file_set_default(m->runtime_scope, force ? UNIT_FILE_FORCE : 0, NULL, name, &changes, &n_changes);
2730 if (r < 0)
2731 return install_error(error, r, changes, n_changes);
2733 return reply_install_changes_and_free(m, message, -1, changes, n_changes, error);
2736 static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2737 InstallChange *changes = NULL;
2738 size_t n_changes = 0;
2739 Manager *m = ASSERT_PTR(userdata);
2740 UnitFilePresetMode preset_mode;
2741 const char *mode;
2742 UnitFileFlags flags;
2743 int force, runtime, r;
2745 assert(message);
2747 r = mac_selinux_access_check(message, "enable", error);
2748 if (r < 0)
2749 return r;
2751 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
2752 if (r < 0)
2753 return r;
2755 flags = unit_file_bools_to_flags(runtime, force);
2757 if (isempty(mode))
2758 preset_mode = UNIT_FILE_PRESET_FULL;
2759 else {
2760 preset_mode = unit_file_preset_mode_from_string(mode);
2761 if (preset_mode < 0)
2762 return -EINVAL;
2765 r = bus_verify_manage_unit_files_async(m, message, error);
2766 if (r < 0)
2767 return r;
2768 if (r == 0)
2769 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2771 r = unit_file_preset_all(m->runtime_scope, flags, NULL, preset_mode, &changes, &n_changes);
2772 if (r < 0)
2773 return install_error(error, r, changes, n_changes);
2775 return reply_install_changes_and_free(m, message, -1, changes, n_changes, error);
2778 static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2779 _cleanup_strv_free_ char **l = NULL;
2780 Manager *m = ASSERT_PTR(userdata);
2781 InstallChange *changes = NULL;
2782 size_t n_changes = 0;
2783 int runtime, force, r;
2784 char *target, *type;
2785 UnitDependency dep;
2786 UnitFileFlags flags;
2788 assert(message);
2790 r = bus_verify_manage_unit_files_async(m, message, error);
2791 if (r < 0)
2792 return r;
2793 if (r == 0)
2794 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2796 r = sd_bus_message_read_strv(message, &l);
2797 if (r < 0)
2798 return r;
2800 r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
2801 if (r < 0)
2802 return r;
2804 flags = unit_file_bools_to_flags(runtime, force);
2806 dep = unit_dependency_from_string(type);
2807 if (dep < 0)
2808 return -EINVAL;
2810 r = unit_file_add_dependency(m->runtime_scope, flags, NULL, l, target, dep, &changes, &n_changes);
2811 if (r < 0)
2812 return install_error(error, r, changes, n_changes);
2814 return reply_install_changes_and_free(m, message, -1, changes, n_changes, error);
2817 static int method_get_unit_file_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2818 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2819 Manager *m = ASSERT_PTR(userdata);
2820 InstallChange *changes = NULL;
2821 size_t n_changes = 0, i;
2822 const char *name;
2823 int runtime, r;
2825 CLEANUP_ARRAY(changes, n_changes, install_changes_free);
2827 r = sd_bus_message_read(message, "sb", &name, &runtime);
2828 if (r < 0)
2829 return r;
2831 r = sd_bus_message_new_method_return(message, &reply);
2832 if (r < 0)
2833 return r;
2835 r = sd_bus_message_open_container(reply, SD_BUS_TYPE_ARRAY, "s");
2836 if (r < 0)
2837 return r;
2839 r = unit_file_disable(m->runtime_scope,
2840 UNIT_FILE_DRY_RUN | (runtime ? UNIT_FILE_RUNTIME : 0),
2841 NULL, STRV_MAKE(name), &changes, &n_changes);
2842 if (r < 0)
2843 return log_error_errno(r, "Failed to get file links for %s: %m", name);
2845 for (i = 0; i < n_changes; i++)
2846 if (changes[i].type == INSTALL_CHANGE_UNLINK) {
2847 r = sd_bus_message_append(reply, "s", changes[i].path);
2848 if (r < 0)
2849 return r;
2852 r = sd_bus_message_close_container(reply);
2853 if (r < 0)
2854 return r;
2856 return sd_bus_send(NULL, reply, NULL);
2859 static int method_get_job_waiting(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2860 Manager *m = ASSERT_PTR(userdata);
2861 uint32_t id;
2862 Job *j;
2863 int r;
2865 assert(message);
2867 r = sd_bus_message_read(message, "u", &id);
2868 if (r < 0)
2869 return r;
2871 j = manager_get_job(m, id);
2872 if (!j)
2873 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
2875 return bus_job_method_get_waiting_jobs(message, j, error);
2878 static int method_abandon_scope(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2879 Manager *m = ASSERT_PTR(userdata);
2880 const char *name;
2881 Unit *u;
2882 int r;
2884 assert(message);
2886 r = sd_bus_message_read(message, "s", &name);
2887 if (r < 0)
2888 return r;
2890 r = bus_get_unit_by_name(m, message, name, &u, error);
2891 if (r < 0)
2892 return r;
2894 if (u->type != UNIT_SCOPE)
2895 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
2896 "Unit '%s' is not a scope unit, refusing.", name);
2898 return bus_scope_method_abandon(message, u, error);
2901 static int method_set_show_status(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2902 Manager *m = ASSERT_PTR(userdata);
2903 ShowStatus mode = _SHOW_STATUS_INVALID;
2904 const char *t;
2905 int r;
2907 assert(message);
2909 r = mac_selinux_access_check(message, "reload", error);
2910 if (r < 0)
2911 return r;
2913 r = bus_verify_set_environment_async(m, message, error);
2914 if (r < 0)
2915 return r;
2916 if (r == 0)
2917 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2919 r = sd_bus_message_read(message, "s", &t);
2920 if (r < 0)
2921 return r;
2923 if (!isempty(t)) {
2924 mode = show_status_from_string(t);
2925 if (mode < 0)
2926 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
2927 "Invalid show status '%s'", t);
2930 manager_override_show_status(m, mode, "bus");
2932 return sd_bus_reply_method_return(message, NULL);
2935 static int method_dump_unit_descriptor_store(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2936 return method_generic_unit_operation(message, userdata, error, bus_service_method_dump_file_descriptor_store, 0);
2939 const sd_bus_vtable bus_manager_vtable[] = {
2940 SD_BUS_VTABLE_START(0),
2942 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2943 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2944 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2945 SD_BUS_PROPERTY("ConfidentialVirtualization", "s", property_get_confidential_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2946 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2947 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2948 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FIRMWARE]), SD_BUS_VTABLE_PROPERTY_CONST),
2949 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_LOADER]), SD_BUS_VTABLE_PROPERTY_CONST),
2950 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_KERNEL]), SD_BUS_VTABLE_PROPERTY_CONST),
2951 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD]), SD_BUS_VTABLE_PROPERTY_CONST),
2952 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_USERSPACE]), SD_BUS_VTABLE_PROPERTY_CONST),
2953 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2954 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2955 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2956 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2957 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2958 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2959 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2960 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD]), SD_BUS_VTABLE_PROPERTY_CONST),
2961 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2962 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2963 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDGeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2964 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDGeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2965 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDUnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST),
2966 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDUnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
2967 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", bus_property_get_log_level, property_set_log_level, 0, 0),
2968 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", bus_property_get_log_target, property_set_log_target, 0, 0),
2969 SD_BUS_PROPERTY("NNames", "u", property_get_hashmap_size, offsetof(Manager, units), 0),
2970 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_set_size, offsetof(Manager, failed_units), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2971 SD_BUS_PROPERTY("NJobs", "u", property_get_hashmap_size, offsetof(Manager, jobs), 0),
2972 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
2973 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
2974 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
2975 SD_BUS_PROPERTY("Environment", "as", property_get_environment, 0, 0),
2976 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
2977 SD_BUS_PROPERTY("ShowStatus", "b", property_get_show_status, 0, 0),
2978 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST),
2979 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
2980 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_error), SD_BUS_VTABLE_PROPERTY_CONST),
2981 SD_BUS_PROPERTY("WatchdogDevice", "s", property_get_watchdog_device, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2982 SD_BUS_PROPERTY("WatchdogLastPingTimestamp", "t", property_get_watchdog_last_ping_realtime, 0, 0),
2983 SD_BUS_PROPERTY("WatchdogLastPingTimestampMonotonic", "t", property_get_watchdog_last_ping_monotonic, 0, 0),
2984 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", property_get_runtime_watchdog, property_set_runtime_watchdog, 0, 0),
2985 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogPreUSec", "t", property_get_pretimeout_watchdog, property_set_pretimeout_watchdog, 0, 0),
2986 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogPreGovernor", "s", property_get_pretimeout_watchdog_governor, property_set_pretimeout_watchdog_governor, 0, 0),
2987 SD_BUS_WRITABLE_PROPERTY("RebootWatchdogUSec", "t", property_get_reboot_watchdog, property_set_reboot_watchdog, 0, 0),
2988 /* The following item is an obsolete alias */
2989 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", property_get_reboot_watchdog, property_set_reboot_watchdog, 0, SD_BUS_VTABLE_HIDDEN),
2990 SD_BUS_WRITABLE_PROPERTY("KExecWatchdogUSec", "t", property_get_kexec_watchdog, property_set_kexec_watchdog, 0, 0),
2991 SD_BUS_WRITABLE_PROPERTY("ServiceWatchdogs", "b", bus_property_get_bool, bus_property_set_bool, offsetof(Manager, service_watchdogs), 0),
2992 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
2993 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
2994 SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0),
2995 SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec, offsetof(Manager, default_timer_accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2996 SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2997 SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2998 SD_BUS_PROPERTY("DefaultTimeoutAbortUSec", "t", property_get_default_timeout_abort_usec, 0, 0),
2999 SD_BUS_PROPERTY("DefaultDeviceTimeoutUSec", "t", bus_property_get_usec, offsetof(Manager, default_device_timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
3000 SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
3001 SD_BUS_PROPERTY("DefaultStartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
3002 /* The following two items are obsolete alias */
3003 SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
3004 SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
3005 SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
3006 SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
3007 SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
3008 SD_BUS_PROPERTY("DefaultIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_io_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
3009 SD_BUS_PROPERTY("DefaultIPAccounting", "b", bus_property_get_bool, offsetof(Manager, default_ip_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
3010 SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, default_memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
3011 SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, default_tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
3012 SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
3013 SD_BUS_PROPERTY("DefaultLimitCPUSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
3014 SD_BUS_PROPERTY("DefaultLimitFSIZE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
3015 SD_BUS_PROPERTY("DefaultLimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
3016 SD_BUS_PROPERTY("DefaultLimitDATA", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
3017 SD_BUS_PROPERTY("DefaultLimitDATASoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
3018 SD_BUS_PROPERTY("DefaultLimitSTACK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
3019 SD_BUS_PROPERTY("DefaultLimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
3020 SD_BUS_PROPERTY("DefaultLimitCORE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
3021 SD_BUS_PROPERTY("DefaultLimitCORESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
3022 SD_BUS_PROPERTY("DefaultLimitRSS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
3023 SD_BUS_PROPERTY("DefaultLimitRSSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
3024 SD_BUS_PROPERTY("DefaultLimitNOFILE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
3025 SD_BUS_PROPERTY("DefaultLimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
3026 SD_BUS_PROPERTY("DefaultLimitAS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
3027 SD_BUS_PROPERTY("DefaultLimitASSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
3028 SD_BUS_PROPERTY("DefaultLimitNPROC", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
3029 SD_BUS_PROPERTY("DefaultLimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
3030 SD_BUS_PROPERTY("DefaultLimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
3031 SD_BUS_PROPERTY("DefaultLimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
3032 SD_BUS_PROPERTY("DefaultLimitLOCKS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
3033 SD_BUS_PROPERTY("DefaultLimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
3034 SD_BUS_PROPERTY("DefaultLimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
3035 SD_BUS_PROPERTY("DefaultLimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
3036 SD_BUS_PROPERTY("DefaultLimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
3037 SD_BUS_PROPERTY("DefaultLimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
3038 SD_BUS_PROPERTY("DefaultLimitNICE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
3039 SD_BUS_PROPERTY("DefaultLimitNICESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
3040 SD_BUS_PROPERTY("DefaultLimitRTPRIO", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
3041 SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
3042 SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
3043 SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
3044 SD_BUS_PROPERTY("DefaultTasksMax", "t", bus_property_get_tasks_max, offsetof(Manager, default_tasks_max), 0),
3045 SD_BUS_PROPERTY("DefaultMemoryPressureThresholdUSec", "t", bus_property_get_usec, offsetof(Manager, default_memory_pressure_threshold_usec), 0),
3046 SD_BUS_PROPERTY("DefaultMemoryPressureWatch", "s", bus_property_get_cgroup_pressure_watch, offsetof(Manager, default_memory_pressure_watch), 0),
3047 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
3048 SD_BUS_PROPERTY("DefaultOOMPolicy", "s", bus_property_get_oom_policy, offsetof(Manager, default_oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
3049 SD_BUS_PROPERTY("DefaultOOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
3050 SD_BUS_PROPERTY("CtrlAltDelBurstAction", "s", bus_property_get_emergency_action, offsetof(Manager, cad_burst_action), SD_BUS_VTABLE_PROPERTY_CONST),
3052 SD_BUS_METHOD_WITH_ARGS("GetUnit",
3053 SD_BUS_ARGS("s", name),
3054 SD_BUS_RESULT("o", unit),
3055 method_get_unit,
3056 SD_BUS_VTABLE_UNPRIVILEGED),
3057 SD_BUS_METHOD_WITH_ARGS("GetUnitByPID",
3058 SD_BUS_ARGS("u", pid),
3059 SD_BUS_RESULT("o", unit),
3060 method_get_unit_by_pid,
3061 SD_BUS_VTABLE_UNPRIVILEGED),
3062 SD_BUS_METHOD_WITH_ARGS("GetUnitByInvocationID",
3063 SD_BUS_ARGS("ay", invocation_id),
3064 SD_BUS_RESULT("o", unit),
3065 method_get_unit_by_invocation_id,
3066 SD_BUS_VTABLE_UNPRIVILEGED),
3067 SD_BUS_METHOD_WITH_ARGS("GetUnitByControlGroup",
3068 SD_BUS_ARGS("s", cgroup),
3069 SD_BUS_RESULT("o", unit),
3070 method_get_unit_by_control_group,
3071 SD_BUS_VTABLE_UNPRIVILEGED),
3072 SD_BUS_METHOD_WITH_ARGS("GetUnitByPIDFD",
3073 SD_BUS_ARGS("h", pidfd),
3074 SD_BUS_RESULT("o", unit, "s", unit_id, "ay", invocation_id),
3075 method_get_unit_by_pidfd,
3076 SD_BUS_VTABLE_UNPRIVILEGED),
3077 SD_BUS_METHOD_WITH_ARGS("LoadUnit",
3078 SD_BUS_ARGS("s", name),
3079 SD_BUS_RESULT("o", unit),
3080 method_load_unit,
3081 SD_BUS_VTABLE_UNPRIVILEGED),
3082 SD_BUS_METHOD_WITH_ARGS("StartUnit",
3083 SD_BUS_ARGS("s", name, "s", mode),
3084 SD_BUS_RESULT("o", job),
3085 method_start_unit,
3086 SD_BUS_VTABLE_UNPRIVILEGED),
3087 SD_BUS_METHOD_WITH_ARGS("StartUnitWithFlags",
3088 SD_BUS_ARGS("s", name, "s", mode, "t", flags),
3089 SD_BUS_RESULT("o", job),
3090 method_start_unit,
3091 SD_BUS_VTABLE_UNPRIVILEGED),
3092 SD_BUS_METHOD_WITH_ARGS("StartUnitReplace",
3093 SD_BUS_ARGS("s", old_unit, "s", new_unit, "s", mode),
3094 SD_BUS_RESULT("o", job),
3095 method_start_unit_replace,
3096 SD_BUS_VTABLE_UNPRIVILEGED),
3097 SD_BUS_METHOD_WITH_ARGS("StopUnit",
3098 SD_BUS_ARGS("s", name, "s", mode),
3099 SD_BUS_RESULT("o", job),
3100 method_stop_unit,
3101 SD_BUS_VTABLE_UNPRIVILEGED),
3102 SD_BUS_METHOD_WITH_ARGS("ReloadUnit",
3103 SD_BUS_ARGS("s", name, "s", mode),
3104 SD_BUS_RESULT("o", job),
3105 method_reload_unit,
3106 SD_BUS_VTABLE_UNPRIVILEGED),
3107 SD_BUS_METHOD_WITH_ARGS("RestartUnit",
3108 SD_BUS_ARGS("s", name, "s", mode),
3109 SD_BUS_RESULT("o", job),
3110 method_restart_unit,
3111 SD_BUS_VTABLE_UNPRIVILEGED),
3112 SD_BUS_METHOD_WITH_ARGS("TryRestartUnit",
3113 SD_BUS_ARGS("s", name, "s", mode),
3114 SD_BUS_RESULT("o", job),
3115 method_try_restart_unit,
3116 SD_BUS_VTABLE_UNPRIVILEGED),
3117 SD_BUS_METHOD_WITH_ARGS("ReloadOrRestartUnit",
3118 SD_BUS_ARGS("s", name, "s", mode),
3119 SD_BUS_RESULT("o", job),
3120 method_reload_or_restart_unit,
3121 SD_BUS_VTABLE_UNPRIVILEGED),
3122 SD_BUS_METHOD_WITH_ARGS("ReloadOrTryRestartUnit",
3123 SD_BUS_ARGS("s", name, "s", mode),
3124 SD_BUS_RESULT("o", job),
3125 method_reload_or_try_restart_unit,
3126 SD_BUS_VTABLE_UNPRIVILEGED),
3127 SD_BUS_METHOD_WITH_ARGS("EnqueueUnitJob",
3128 SD_BUS_ARGS("s", name, "s", job_type, "s", job_mode),
3129 SD_BUS_RESULT("u", job_id, "o", job_path, "s", unit_id, "o", unit_path, "s", job_type, "a(uosos)", affected_jobs),
3130 method_enqueue_unit_job,
3131 SD_BUS_VTABLE_UNPRIVILEGED),
3132 SD_BUS_METHOD_WITH_ARGS("KillUnit",
3133 SD_BUS_ARGS("s", name, "s", whom, "i", signal),
3134 SD_BUS_NO_RESULT,
3135 method_kill_unit,
3136 SD_BUS_VTABLE_UNPRIVILEGED),
3137 SD_BUS_METHOD_WITH_ARGS("QueueSignalUnit",
3138 SD_BUS_ARGS("s", name, "s", whom, "i", signal, "i", value),
3139 SD_BUS_NO_RESULT,
3140 method_kill_unit,
3141 SD_BUS_VTABLE_UNPRIVILEGED),
3142 SD_BUS_METHOD_WITH_ARGS("CleanUnit",
3143 SD_BUS_ARGS("s", name, "as", mask),
3144 SD_BUS_NO_RESULT,
3145 method_clean_unit,
3146 SD_BUS_VTABLE_UNPRIVILEGED),
3147 SD_BUS_METHOD_WITH_ARGS("FreezeUnit",
3148 SD_BUS_ARGS("s", name),
3149 SD_BUS_NO_RESULT,
3150 method_freeze_unit,
3151 SD_BUS_VTABLE_UNPRIVILEGED),
3152 SD_BUS_METHOD_WITH_ARGS("ThawUnit",
3153 SD_BUS_ARGS("s", name),
3154 SD_BUS_NO_RESULT,
3155 method_thaw_unit,
3156 SD_BUS_VTABLE_UNPRIVILEGED),
3157 SD_BUS_METHOD_WITH_ARGS("ResetFailedUnit",
3158 SD_BUS_ARGS("s", name),
3159 SD_BUS_NO_RESULT,
3160 method_reset_failed_unit,
3161 SD_BUS_VTABLE_UNPRIVILEGED),
3162 SD_BUS_METHOD_WITH_ARGS("SetUnitProperties",
3163 SD_BUS_ARGS("s", name, "b", runtime, "a(sv)", properties),
3164 SD_BUS_NO_RESULT,
3165 method_set_unit_properties,
3166 SD_BUS_VTABLE_UNPRIVILEGED),
3167 SD_BUS_METHOD_WITH_ARGS("BindMountUnit",
3168 SD_BUS_ARGS("s", name, "s", source, "s", destination, "b", read_only, "b", mkdir),
3169 SD_BUS_NO_RESULT,
3170 method_bind_mount_unit,
3171 SD_BUS_VTABLE_UNPRIVILEGED),
3172 SD_BUS_METHOD_WITH_ARGS("MountImageUnit",
3173 SD_BUS_ARGS("s", name, "s", source, "s", destination, "b", read_only, "b", mkdir, "a(ss)", options),
3174 SD_BUS_NO_RESULT,
3175 method_mount_image_unit,
3176 SD_BUS_VTABLE_UNPRIVILEGED),
3177 SD_BUS_METHOD_WITH_ARGS("RefUnit",
3178 SD_BUS_ARGS("s", name),
3179 SD_BUS_NO_RESULT,
3180 method_ref_unit,
3181 SD_BUS_VTABLE_UNPRIVILEGED),
3182 SD_BUS_METHOD_WITH_ARGS("UnrefUnit",
3183 SD_BUS_ARGS("s", name),
3184 SD_BUS_NO_RESULT,
3185 method_unref_unit,
3186 SD_BUS_VTABLE_UNPRIVILEGED),
3187 SD_BUS_METHOD_WITH_ARGS("StartTransientUnit",
3188 SD_BUS_ARGS("s", name, "s", mode, "a(sv)", properties, "a(sa(sv))", aux),
3189 SD_BUS_RESULT("o", job),
3190 method_start_transient_unit,
3191 SD_BUS_VTABLE_UNPRIVILEGED),
3192 SD_BUS_METHOD_WITH_ARGS("GetUnitProcesses",
3193 SD_BUS_ARGS("s", name),
3194 SD_BUS_RESULT("a(sus)", processes),
3195 method_get_unit_processes,
3196 SD_BUS_VTABLE_UNPRIVILEGED),
3197 SD_BUS_METHOD_WITH_ARGS("AttachProcessesToUnit",
3198 SD_BUS_ARGS("s", unit_name, "s", subcgroup, "au", pids),
3199 SD_BUS_NO_RESULT,
3200 method_attach_processes_to_unit,
3201 SD_BUS_VTABLE_UNPRIVILEGED),
3202 SD_BUS_METHOD_WITH_ARGS("AbandonScope",
3203 SD_BUS_ARGS("s", name),
3204 SD_BUS_NO_RESULT,
3205 method_abandon_scope,
3206 SD_BUS_VTABLE_UNPRIVILEGED),
3207 SD_BUS_METHOD_WITH_ARGS("GetJob",
3208 SD_BUS_ARGS("u", id),
3209 SD_BUS_RESULT("o", job),
3210 method_get_job,
3211 SD_BUS_VTABLE_UNPRIVILEGED),
3212 SD_BUS_METHOD_WITH_ARGS("GetJobAfter",
3213 SD_BUS_ARGS("u", id),
3214 SD_BUS_RESULT("a(usssoo)", jobs),
3215 method_get_job_waiting,
3216 SD_BUS_VTABLE_UNPRIVILEGED),
3217 SD_BUS_METHOD_WITH_ARGS("GetJobBefore",
3218 SD_BUS_ARGS("u", id),
3219 SD_BUS_RESULT("a(usssoo)", jobs),
3220 method_get_job_waiting,
3221 SD_BUS_VTABLE_UNPRIVILEGED),
3222 SD_BUS_METHOD_WITH_ARGS("CancelJob",
3223 SD_BUS_ARGS("u", id),
3224 SD_BUS_NO_RESULT,
3225 method_cancel_job,
3226 SD_BUS_VTABLE_UNPRIVILEGED),
3227 SD_BUS_METHOD("ClearJobs",
3228 NULL,
3229 NULL,
3230 method_clear_jobs,
3231 SD_BUS_VTABLE_UNPRIVILEGED),
3232 SD_BUS_METHOD("ResetFailed",
3233 NULL,
3234 NULL,
3235 method_reset_failed,
3236 SD_BUS_VTABLE_UNPRIVILEGED),
3237 SD_BUS_METHOD_WITH_ARGS("SetShowStatus",
3238 SD_BUS_ARGS("s", mode),
3239 SD_BUS_NO_RESULT,
3240 method_set_show_status,
3241 SD_BUS_VTABLE_UNPRIVILEGED),
3242 SD_BUS_METHOD_WITH_ARGS("ListUnits",
3243 SD_BUS_NO_ARGS,
3244 SD_BUS_RESULT("a(ssssssouso)", units),
3245 method_list_units,
3246 SD_BUS_VTABLE_UNPRIVILEGED),
3247 SD_BUS_METHOD_WITH_ARGS("ListUnitsFiltered",
3248 SD_BUS_ARGS("as", states),
3249 SD_BUS_RESULT("a(ssssssouso)", units),
3250 method_list_units_filtered,
3251 SD_BUS_VTABLE_UNPRIVILEGED),
3252 SD_BUS_METHOD_WITH_ARGS("ListUnitsByPatterns",
3253 SD_BUS_ARGS("as", states, "as", patterns),
3254 SD_BUS_RESULT("a(ssssssouso)", units),
3255 method_list_units_by_patterns,
3256 SD_BUS_VTABLE_UNPRIVILEGED),
3257 SD_BUS_METHOD_WITH_ARGS("ListUnitsByNames",
3258 SD_BUS_ARGS("as", names),
3259 SD_BUS_RESULT("a(ssssssouso)", units),
3260 method_list_units_by_names,
3261 SD_BUS_VTABLE_UNPRIVILEGED),
3262 SD_BUS_METHOD_WITH_ARGS("ListJobs",
3263 SD_BUS_NO_ARGS,
3264 SD_BUS_RESULT("a(usssoo)", jobs),
3265 method_list_jobs,
3266 SD_BUS_VTABLE_UNPRIVILEGED),
3267 SD_BUS_METHOD("Subscribe",
3268 NULL,
3269 NULL,
3270 method_subscribe,
3271 SD_BUS_VTABLE_UNPRIVILEGED),
3272 SD_BUS_METHOD("Unsubscribe",
3273 NULL,
3274 NULL,
3275 method_unsubscribe,
3276 SD_BUS_VTABLE_UNPRIVILEGED),
3277 SD_BUS_METHOD_WITH_ARGS("Dump",
3278 SD_BUS_NO_ARGS,
3279 SD_BUS_RESULT("s", output),
3280 method_dump,
3281 SD_BUS_VTABLE_UNPRIVILEGED),
3282 SD_BUS_METHOD_WITH_ARGS("DumpUnitsMatchingPatterns",
3283 SD_BUS_ARGS("as", patterns),
3284 SD_BUS_RESULT("s", output),
3285 method_dump_units_matching_patterns,
3286 SD_BUS_VTABLE_UNPRIVILEGED),
3287 SD_BUS_METHOD_WITH_ARGS("DumpByFileDescriptor",
3288 SD_BUS_NO_ARGS,
3289 SD_BUS_RESULT("h", fd),
3290 method_dump_by_fd,
3291 SD_BUS_VTABLE_UNPRIVILEGED),
3292 SD_BUS_METHOD_WITH_ARGS("DumpUnitsMatchingPatternsByFileDescriptor",
3293 SD_BUS_ARGS("as", patterns),
3294 SD_BUS_RESULT("h", fd),
3295 method_dump_units_matching_patterns_by_fd,
3296 SD_BUS_VTABLE_UNPRIVILEGED),
3297 SD_BUS_METHOD_WITH_ARGS("CreateSnapshot",
3298 SD_BUS_ARGS("s", name, "b", cleanup),
3299 SD_BUS_RESULT("o", unit),
3300 method_refuse_snapshot,
3301 SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
3302 SD_BUS_METHOD_WITH_ARGS("RemoveSnapshot",
3303 SD_BUS_ARGS("s", name),
3304 SD_BUS_NO_RESULT,
3305 method_refuse_snapshot,
3306 SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
3307 SD_BUS_METHOD("Reload",
3308 NULL,
3309 NULL,
3310 method_reload,
3311 SD_BUS_VTABLE_UNPRIVILEGED),
3312 SD_BUS_METHOD("Reexecute",
3313 NULL,
3314 NULL,
3315 method_reexecute,
3316 SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_METHOD_NO_REPLY),
3317 SD_BUS_METHOD("Exit",
3318 NULL,
3319 NULL,
3320 method_exit,
3322 SD_BUS_METHOD("Reboot",
3323 NULL,
3324 NULL,
3325 method_reboot,
3326 SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3327 SD_BUS_METHOD_WITH_ARGS("SoftReboot",
3328 SD_BUS_ARGS("s", new_root),
3329 SD_BUS_NO_RESULT,
3330 method_soft_reboot,
3331 SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3332 SD_BUS_METHOD("PowerOff",
3333 NULL,
3334 NULL,
3335 method_poweroff,
3336 SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3337 SD_BUS_METHOD("Halt",
3338 NULL,
3339 NULL,
3340 method_halt,
3341 SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3342 SD_BUS_METHOD("KExec",
3343 NULL,
3344 NULL,
3345 method_kexec,
3346 SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3347 SD_BUS_METHOD_WITH_ARGS("SwitchRoot",
3348 SD_BUS_ARGS("s", new_root, "s", init),
3349 SD_BUS_NO_RESULT,
3350 method_switch_root,
3351 SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
3352 SD_BUS_METHOD_WITH_ARGS("SetEnvironment",
3353 SD_BUS_ARGS("as", assignments),
3354 SD_BUS_NO_RESULT,
3355 method_set_environment,
3356 SD_BUS_VTABLE_UNPRIVILEGED),
3357 SD_BUS_METHOD_WITH_ARGS("UnsetEnvironment",
3358 SD_BUS_ARGS("as", names),
3359 SD_BUS_NO_RESULT,
3360 method_unset_environment,
3361 SD_BUS_VTABLE_UNPRIVILEGED),
3362 SD_BUS_METHOD_WITH_ARGS("UnsetAndSetEnvironment",
3363 SD_BUS_ARGS("as", names, "as", assignments),
3364 SD_BUS_NO_RESULT,
3365 method_unset_and_set_environment,
3366 SD_BUS_VTABLE_UNPRIVILEGED),
3367 SD_BUS_METHOD_WITH_ARGS("EnqueueMarkedJobs",
3368 SD_BUS_NO_ARGS,
3369 SD_BUS_RESULT("ao", jobs),
3370 method_enqueue_marked_jobs,
3371 SD_BUS_VTABLE_UNPRIVILEGED),
3372 SD_BUS_METHOD_WITH_ARGS("ListUnitFiles",
3373 SD_BUS_NO_ARGS,
3374 SD_BUS_RESULT("a(ss)", unit_files),
3375 method_list_unit_files,
3376 SD_BUS_VTABLE_UNPRIVILEGED),
3377 SD_BUS_METHOD_WITH_ARGS("ListUnitFilesByPatterns",
3378 SD_BUS_ARGS("as", states, "as", patterns),
3379 SD_BUS_RESULT("a(ss)", unit_files),
3380 method_list_unit_files_by_patterns,
3381 SD_BUS_VTABLE_UNPRIVILEGED),
3382 SD_BUS_METHOD_WITH_ARGS("GetUnitFileState",
3383 SD_BUS_ARGS("s", file),
3384 SD_BUS_RESULT("s", state),
3385 method_get_unit_file_state,
3386 SD_BUS_VTABLE_UNPRIVILEGED),
3387 SD_BUS_METHOD_WITH_ARGS("EnableUnitFiles",
3388 SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3389 SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3390 method_enable_unit_files,
3391 SD_BUS_VTABLE_UNPRIVILEGED),
3392 SD_BUS_METHOD_WITH_ARGS("DisableUnitFiles",
3393 SD_BUS_ARGS("as", files, "b", runtime),
3394 SD_BUS_RESULT("a(sss)", changes),
3395 method_disable_unit_files,
3396 SD_BUS_VTABLE_UNPRIVILEGED),
3397 SD_BUS_METHOD_WITH_ARGS("EnableUnitFilesWithFlags",
3398 SD_BUS_ARGS("as", files, "t", flags),
3399 SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3400 method_enable_unit_files_with_flags,
3401 SD_BUS_VTABLE_UNPRIVILEGED),
3402 SD_BUS_METHOD_WITH_ARGS("DisableUnitFilesWithFlags",
3403 SD_BUS_ARGS("as", files, "t", flags),
3404 SD_BUS_RESULT("a(sss)", changes),
3405 method_disable_unit_files_with_flags,
3406 SD_BUS_VTABLE_UNPRIVILEGED),
3407 SD_BUS_METHOD_WITH_ARGS("DisableUnitFilesWithFlagsAndInstallInfo",
3408 SD_BUS_ARGS("as", files, "t", flags),
3409 SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3410 method_disable_unit_files_with_flags_and_install_info,
3411 SD_BUS_VTABLE_UNPRIVILEGED),
3412 SD_BUS_METHOD_WITH_ARGS("ReenableUnitFiles",
3413 SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3414 SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3415 method_reenable_unit_files,
3416 SD_BUS_VTABLE_UNPRIVILEGED),
3417 SD_BUS_METHOD_WITH_ARGS("LinkUnitFiles",
3418 SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3419 SD_BUS_RESULT("a(sss)", changes),
3420 method_link_unit_files,
3421 SD_BUS_VTABLE_UNPRIVILEGED),
3422 SD_BUS_METHOD_WITH_ARGS("PresetUnitFiles",
3423 SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3424 SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3425 method_preset_unit_files,
3426 SD_BUS_VTABLE_UNPRIVILEGED),
3427 SD_BUS_METHOD_WITH_ARGS("PresetUnitFilesWithMode",
3428 SD_BUS_ARGS("as", files, "s", mode, "b", runtime, "b", force),
3429 SD_BUS_RESULT("b", carries_install_info, "a(sss)", changes),
3430 method_preset_unit_files_with_mode,
3431 SD_BUS_VTABLE_UNPRIVILEGED),
3432 SD_BUS_METHOD_WITH_ARGS("MaskUnitFiles",
3433 SD_BUS_ARGS("as", files, "b", runtime, "b", force),
3434 SD_BUS_RESULT("a(sss)", changes),
3435 method_mask_unit_files,
3436 SD_BUS_VTABLE_UNPRIVILEGED),
3437 SD_BUS_METHOD_WITH_ARGS("UnmaskUnitFiles",
3438 SD_BUS_ARGS("as", files, "b", runtime),
3439 SD_BUS_RESULT("a(sss)", changes),
3440 method_unmask_unit_files,
3441 SD_BUS_VTABLE_UNPRIVILEGED),
3442 SD_BUS_METHOD_WITH_ARGS("RevertUnitFiles",
3443 SD_BUS_ARGS("as", files),
3444 SD_BUS_RESULT("a(sss)", changes),
3445 method_revert_unit_files,
3446 SD_BUS_VTABLE_UNPRIVILEGED),
3447 SD_BUS_METHOD_WITH_ARGS("SetDefaultTarget",
3448 SD_BUS_ARGS("s", name, "b", force),
3449 SD_BUS_RESULT("a(sss)", changes),
3450 method_set_default_target,
3451 SD_BUS_VTABLE_UNPRIVILEGED),
3452 SD_BUS_METHOD_WITH_ARGS("GetDefaultTarget",
3453 SD_BUS_NO_ARGS,
3454 SD_BUS_RESULT("s", name),
3455 method_get_default_target,
3456 SD_BUS_VTABLE_UNPRIVILEGED),
3457 SD_BUS_METHOD_WITH_ARGS("PresetAllUnitFiles",
3458 SD_BUS_ARGS("s", mode, "b", runtime, "b", force),
3459 SD_BUS_RESULT("a(sss)", changes),
3460 method_preset_all_unit_files,
3461 SD_BUS_VTABLE_UNPRIVILEGED),
3462 SD_BUS_METHOD_WITH_ARGS("AddDependencyUnitFiles",
3463 SD_BUS_ARGS("as", files, "s", target, "s", type, "b", runtime, "b", force),
3464 SD_BUS_RESULT("a(sss)", changes),
3465 method_add_dependency_unit_files,
3466 SD_BUS_VTABLE_UNPRIVILEGED),
3467 SD_BUS_METHOD_WITH_ARGS("GetUnitFileLinks",
3468 SD_BUS_ARGS("s", name, "b", runtime),
3469 SD_BUS_RESULT("as", links),
3470 method_get_unit_file_links,
3471 SD_BUS_VTABLE_UNPRIVILEGED),
3472 SD_BUS_METHOD_WITH_ARGS("SetExitCode",
3473 SD_BUS_ARGS("y", number),
3474 SD_BUS_NO_RESULT,
3475 method_set_exit_code,
3476 SD_BUS_VTABLE_UNPRIVILEGED),
3477 SD_BUS_METHOD_WITH_ARGS("LookupDynamicUserByName",
3478 SD_BUS_ARGS("s", name),
3479 SD_BUS_RESULT("u", uid),
3480 method_lookup_dynamic_user_by_name,
3481 SD_BUS_VTABLE_UNPRIVILEGED),
3482 SD_BUS_METHOD_WITH_ARGS("LookupDynamicUserByUID",
3483 SD_BUS_ARGS("u", uid),
3484 SD_BUS_RESULT("s", name),
3485 method_lookup_dynamic_user_by_uid,
3486 SD_BUS_VTABLE_UNPRIVILEGED),
3487 SD_BUS_METHOD_WITH_ARGS("GetDynamicUsers",
3488 SD_BUS_NO_ARGS,
3489 SD_BUS_RESULT("a(us)", users),
3490 method_get_dynamic_users,
3491 SD_BUS_VTABLE_UNPRIVILEGED),
3492 SD_BUS_METHOD_WITH_ARGS("DumpUnitFileDescriptorStore",
3493 SD_BUS_ARGS("s", name),
3494 SD_BUS_RESULT("a(suuutuusu)", entries),
3495 method_dump_unit_descriptor_store,
3496 SD_BUS_VTABLE_UNPRIVILEGED),
3498 SD_BUS_SIGNAL_WITH_ARGS("UnitNew",
3499 SD_BUS_ARGS("s", id, "o", unit),
3501 SD_BUS_SIGNAL_WITH_ARGS("UnitRemoved",
3502 SD_BUS_ARGS("s", id, "o", unit),
3504 SD_BUS_SIGNAL_WITH_ARGS("JobNew",
3505 SD_BUS_ARGS("u", id, "o", job, "s", unit),
3507 SD_BUS_SIGNAL_WITH_ARGS("JobRemoved",
3508 SD_BUS_ARGS("u", id, "o", job, "s", unit, "s", result),
3510 SD_BUS_SIGNAL_WITH_ARGS("StartupFinished",
3511 SD_BUS_ARGS("t", firmware, "t", loader, "t", kernel, "t", initrd, "t", userspace, "t", total),
3513 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
3514 SD_BUS_SIGNAL_WITH_ARGS("Reloading",
3515 SD_BUS_ARGS("b", active),
3518 SD_BUS_VTABLE_END
3521 const sd_bus_vtable bus_manager_log_control_vtable[] = {
3522 SD_BUS_VTABLE_START(0),
3524 /* We define a private version of this interface here, since we want slightly different
3525 * implementations for the setters. We'll still use the generic getters however, and we share the
3526 * setters with the implementations for the Manager interface above (which pre-dates the generic
3527 * service API interface). */
3529 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", bus_property_get_log_level, property_set_log_level, 0, 0),
3530 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", bus_property_get_log_target, property_set_log_target, 0, 0),
3531 SD_BUS_PROPERTY("SyslogIdentifier", "s", bus_property_get_syslog_identifier, 0, 0),
3533 SD_BUS_VTABLE_END,
3536 static int send_finished(sd_bus *bus, void *userdata) {
3537 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
3538 usec_t *times = ASSERT_PTR(userdata);
3539 int r;
3541 assert(bus);
3543 r = sd_bus_message_new_signal(bus,
3544 &message,
3545 "/org/freedesktop/systemd1",
3546 "org.freedesktop.systemd1.Manager",
3547 "StartupFinished");
3548 if (r < 0)
3549 return r;
3551 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
3552 if (r < 0)
3553 return r;
3555 return sd_bus_send(bus, message, NULL);
3558 void bus_manager_send_finished(
3559 Manager *m,
3560 usec_t firmware_usec,
3561 usec_t loader_usec,
3562 usec_t kernel_usec,
3563 usec_t initrd_usec,
3564 usec_t userspace_usec,
3565 usec_t total_usec) {
3567 int r;
3569 assert(m);
3571 r = bus_foreach_bus(
3573 NULL,
3574 send_finished,
3575 (usec_t[6]) {
3576 firmware_usec,
3577 loader_usec,
3578 kernel_usec,
3579 initrd_usec,
3580 userspace_usec,
3581 total_usec
3583 if (r < 0)
3584 log_debug_errno(r, "Failed to send finished signal: %m");
3587 static int send_reloading(sd_bus *bus, void *userdata) {
3588 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
3589 int r;
3591 assert(bus);
3593 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
3594 if (r < 0)
3595 return r;
3597 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
3598 if (r < 0)
3599 return r;
3601 return sd_bus_send(bus, message, NULL);
3604 void bus_manager_send_reloading(Manager *m, bool active) {
3605 int r;
3607 assert(m);
3609 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
3610 if (r < 0)
3611 log_debug_errno(r, "Failed to send reloading signal: %m");
3614 static int send_changed_signal(sd_bus *bus, void *userdata) {
3615 assert(bus);
3617 return sd_bus_emit_properties_changed_strv(bus,
3618 "/org/freedesktop/systemd1",
3619 "org.freedesktop.systemd1.Manager",
3620 NULL);
3623 void bus_manager_send_change_signal(Manager *m) {
3624 int r;
3626 assert(m);
3628 r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
3629 if (r < 0)
3630 log_debug_errno(r, "Failed to send manager change signal: %m");