]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-manager.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / core / dbus-manager.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22 #include <sys/prctl.h>
23 #include <sys/statvfs.h>
24 #include <unistd.h>
25
26 #include "alloc-util.h"
27 #include "architecture.h"
28 #include "build.h"
29 #include "bus-common-errors.h"
30 #include "clock-util.h"
31 #include "dbus-execute.h"
32 #include "dbus-job.h"
33 #include "dbus-manager.h"
34 #include "dbus-unit.h"
35 #include "dbus.h"
36 #include "env-util.h"
37 #include "fd-util.h"
38 #include "fileio.h"
39 #include "format-util.h"
40 #include "fs-util.h"
41 #include "install.h"
42 #include "log.h"
43 #include "parse-util.h"
44 #include "path-util.h"
45 #include "selinux-access.h"
46 #include "stat-util.h"
47 #include "string-util.h"
48 #include "strv.h"
49 #include "syslog-util.h"
50 #include "user-util.h"
51 #include "virt.h"
52 #include "watchdog.h"
53
54 /* Require 16MiB free in /run/systemd for reloading/reexecing. After all we need to serialize our state there, and if
55 * we can't we'll fail badly. */
56 #define RELOAD_DISK_SPACE_MIN (UINT64_C(16) * UINT64_C(1024) * UINT64_C(1024))
57
58 static UnitFileFlags unit_file_bools_to_flags(bool runtime, bool force) {
59 return (runtime ? UNIT_FILE_RUNTIME : 0) |
60 (force ? UNIT_FILE_FORCE : 0);
61 }
62
63 static int property_get_version(
64 sd_bus *bus,
65 const char *path,
66 const char *interface,
67 const char *property,
68 sd_bus_message *reply,
69 void *userdata,
70 sd_bus_error *error) {
71
72 assert(bus);
73 assert(reply);
74
75 return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
76 }
77
78 static int property_get_features(
79 sd_bus *bus,
80 const char *path,
81 const char *interface,
82 const char *property,
83 sd_bus_message *reply,
84 void *userdata,
85 sd_bus_error *error) {
86
87 assert(bus);
88 assert(reply);
89
90 return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
91 }
92
93 static int property_get_virtualization(
94 sd_bus *bus,
95 const char *path,
96 const char *interface,
97 const char *property,
98 sd_bus_message *reply,
99 void *userdata,
100 sd_bus_error *error) {
101
102 int v;
103
104 assert(bus);
105 assert(reply);
106
107 v = detect_virtualization();
108
109 /* Make sure to return the empty string when we detect no virtualization, as that is the API.
110 *
111 * https://github.com/systemd/systemd/issues/1423
112 */
113
114 return sd_bus_message_append(
115 reply, "s",
116 v == VIRTUALIZATION_NONE ? "" : virtualization_to_string(v));
117 }
118
119 static int property_get_architecture(
120 sd_bus *bus,
121 const char *path,
122 const char *interface,
123 const char *property,
124 sd_bus_message *reply,
125 void *userdata,
126 sd_bus_error *error) {
127
128 assert(bus);
129 assert(reply);
130
131 return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
132 }
133
134 static int property_get_tainted(
135 sd_bus *bus,
136 const char *path,
137 const char *interface,
138 const char *property,
139 sd_bus_message *reply,
140 void *userdata,
141 sd_bus_error *error) {
142
143 char buf[sizeof("split-usr:cgroups-missing:local-hwclock:var-run-bad:")] = "", *e = buf;
144 _cleanup_free_ char *destination = NULL;
145 Manager *m = userdata;
146 int r;
147
148 assert(bus);
149 assert(reply);
150 assert(m);
151
152 if (m->taint_usr)
153 e = stpcpy(e, "split-usr:");
154
155 if (access("/proc/cgroups", F_OK) < 0)
156 e = stpcpy(e, "cgroups-missing:");
157
158 if (clock_is_localtime(NULL) > 0)
159 e = stpcpy(e, "local-hwclock:");
160
161 r = readlink_malloc("/var/run", &destination);
162 if (r < 0 || !PATH_IN_SET(destination, "../run", "/run"))
163 e = stpcpy(e, "var-run-bad:");
164
165 /* remove the last ':' */
166 if (e != buf)
167 e[-1] = 0;
168
169 return sd_bus_message_append(reply, "s", buf);
170 }
171
172 static int property_get_log_target(
173 sd_bus *bus,
174 const char *path,
175 const char *interface,
176 const char *property,
177 sd_bus_message *reply,
178 void *userdata,
179 sd_bus_error *error) {
180
181 assert(bus);
182 assert(reply);
183
184 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
185 }
186
187 static int property_set_log_target(
188 sd_bus *bus,
189 const char *path,
190 const char *interface,
191 const char *property,
192 sd_bus_message *value,
193 void *userdata,
194 sd_bus_error *error) {
195
196 const char *t;
197 int r;
198
199 assert(bus);
200 assert(value);
201
202 r = sd_bus_message_read(value, "s", &t);
203 if (r < 0)
204 return r;
205
206 return log_set_target_from_string(t);
207 }
208
209 static int property_get_log_level(
210 sd_bus *bus,
211 const char *path,
212 const char *interface,
213 const char *property,
214 sd_bus_message *reply,
215 void *userdata,
216 sd_bus_error *error) {
217
218 _cleanup_free_ char *t = NULL;
219 int r;
220
221 assert(bus);
222 assert(reply);
223
224 r = log_level_to_string_alloc(log_get_max_level(), &t);
225 if (r < 0)
226 return r;
227
228 return sd_bus_message_append(reply, "s", t);
229 }
230
231 static int property_set_log_level(
232 sd_bus *bus,
233 const char *path,
234 const char *interface,
235 const char *property,
236 sd_bus_message *value,
237 void *userdata,
238 sd_bus_error *error) {
239
240 const char *t;
241 int r;
242
243 assert(bus);
244 assert(value);
245
246 r = sd_bus_message_read(value, "s", &t);
247 if (r < 0)
248 return r;
249
250 r = log_set_max_level_from_string(t);
251 if (r == 0)
252 log_info("Setting log level to %s.", t);
253 return r;
254 }
255
256 static int property_get_n_names(
257 sd_bus *bus,
258 const char *path,
259 const char *interface,
260 const char *property,
261 sd_bus_message *reply,
262 void *userdata,
263 sd_bus_error *error) {
264
265 Manager *m = userdata;
266
267 assert(bus);
268 assert(reply);
269 assert(m);
270
271 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
272 }
273
274 static int property_get_n_failed_units(
275 sd_bus *bus,
276 const char *path,
277 const char *interface,
278 const char *property,
279 sd_bus_message *reply,
280 void *userdata,
281 sd_bus_error *error) {
282
283 Manager *m = userdata;
284
285 assert(bus);
286 assert(reply);
287 assert(m);
288
289 return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
290 }
291
292 static int property_get_n_jobs(
293 sd_bus *bus,
294 const char *path,
295 const char *interface,
296 const char *property,
297 sd_bus_message *reply,
298 void *userdata,
299 sd_bus_error *error) {
300
301 Manager *m = userdata;
302
303 assert(bus);
304 assert(reply);
305 assert(m);
306
307 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
308 }
309
310 static int property_get_progress(
311 sd_bus *bus,
312 const char *path,
313 const char *interface,
314 const char *property,
315 sd_bus_message *reply,
316 void *userdata,
317 sd_bus_error *error) {
318
319 Manager *m = userdata;
320 double d;
321
322 assert(bus);
323 assert(reply);
324 assert(m);
325
326 if (dual_timestamp_is_set(&m->finish_timestamp))
327 d = 1.0;
328 else
329 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
330
331 return sd_bus_message_append(reply, "d", d);
332 }
333
334 static int property_get_system_state(
335 sd_bus *bus,
336 const char *path,
337 const char *interface,
338 const char *property,
339 sd_bus_message *reply,
340 void *userdata,
341 sd_bus_error *error) {
342
343 Manager *m = userdata;
344
345 assert(bus);
346 assert(reply);
347 assert(m);
348
349 return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
350 }
351
352 static int property_set_runtime_watchdog(
353 sd_bus *bus,
354 const char *path,
355 const char *interface,
356 const char *property,
357 sd_bus_message *value,
358 void *userdata,
359 sd_bus_error *error) {
360
361 usec_t *t = userdata;
362 int r;
363
364 assert(bus);
365 assert(value);
366
367 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
368
369 r = sd_bus_message_read(value, "t", t);
370 if (r < 0)
371 return r;
372
373 return watchdog_set_timeout(t);
374 }
375
376 static int property_get_timer_slack_nsec(
377 sd_bus *bus,
378 const char *path,
379 const char *interface,
380 const char *property,
381 sd_bus_message *reply,
382 void *userdata,
383 sd_bus_error *error) {
384
385 assert(bus);
386 assert(reply);
387
388 return sd_bus_message_append(reply, "t", (uint64_t) prctl(PR_GET_TIMERSLACK));
389 }
390
391 static int method_get_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
392 _cleanup_free_ char *path = NULL;
393 Manager *m = userdata;
394 const char *name;
395 Unit *u;
396 int r;
397
398 assert(message);
399 assert(m);
400
401 /* Anyone can call this method */
402
403 r = sd_bus_message_read(message, "s", &name);
404 if (r < 0)
405 return r;
406
407 if (isempty(name)) {
408 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
409 pid_t pid;
410
411 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
412 if (r < 0)
413 return r;
414
415 r = sd_bus_creds_get_pid(creds, &pid);
416 if (r < 0)
417 return r;
418
419 u = manager_get_unit_by_pid(m, pid);
420 if (!u)
421 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
422 } else {
423 u = manager_get_unit(m, name);
424 if (!u)
425 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
426 }
427
428 r = mac_selinux_unit_access_check(u, message, "status", error);
429 if (r < 0)
430 return r;
431
432 path = unit_dbus_path(u);
433 if (!path)
434 return -ENOMEM;
435
436 return sd_bus_reply_method_return(message, "o", path);
437 }
438
439 static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
440 _cleanup_free_ char *path = NULL;
441 Manager *m = userdata;
442 pid_t pid;
443 Unit *u;
444 int r;
445
446 assert(message);
447 assert(m);
448
449 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
450
451 /* Anyone can call this method */
452
453 r = sd_bus_message_read(message, "u", &pid);
454 if (r < 0)
455 return r;
456 if (pid < 0)
457 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
458
459 if (pid == 0) {
460 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
461
462 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
463 if (r < 0)
464 return r;
465
466 r = sd_bus_creds_get_pid(creds, &pid);
467 if (r < 0)
468 return r;
469 }
470
471 u = manager_get_unit_by_pid(m, pid);
472 if (!u)
473 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
474
475 r = mac_selinux_unit_access_check(u, message, "status", error);
476 if (r < 0)
477 return r;
478
479 path = unit_dbus_path(u);
480 if (!path)
481 return -ENOMEM;
482
483 return sd_bus_reply_method_return(message, "o", path);
484 }
485
486 static int method_get_unit_by_invocation_id(sd_bus_message *message, void *userdata, sd_bus_error *error) {
487 _cleanup_free_ char *path = NULL;
488 Manager *m = userdata;
489 sd_id128_t id;
490 const void *a;
491 Unit *u;
492 size_t sz;
493 int r;
494
495 assert(message);
496 assert(m);
497
498 /* Anyone can call this method */
499
500 r = sd_bus_message_read_array(message, 'y', &a, &sz);
501 if (r < 0)
502 return r;
503 if (sz == 0)
504 id = SD_ID128_NULL;
505 else if (sz == 16)
506 memcpy(&id, a, sz);
507 else
508 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid invocation ID");
509
510 if (sd_id128_is_null(id)) {
511 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
512 pid_t pid;
513
514 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
515 if (r < 0)
516 return r;
517
518 r = sd_bus_creds_get_pid(creds, &pid);
519 if (r < 0)
520 return r;
521
522 u = manager_get_unit_by_pid(m, pid);
523 if (!u)
524 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client " PID_FMT " not member of any unit.", pid);
525 } else {
526 u = hashmap_get(m->units_by_invocation_id, &id);
527 if (!u)
528 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));
529 }
530
531 r = mac_selinux_unit_access_check(u, message, "status", error);
532 if (r < 0)
533 return r;
534
535 /* So here's a special trick: the bus path we return actually references the unit by its invocation ID instead
536 * of the unit name. This means it stays valid only as long as the invocation ID stays the same. */
537 path = unit_dbus_path_invocation_id(u);
538 if (!path)
539 return -ENOMEM;
540
541 return sd_bus_reply_method_return(message, "o", path);
542 }
543
544 static int method_load_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
545 _cleanup_free_ char *path = NULL;
546 Manager *m = userdata;
547 const char *name;
548 Unit *u;
549 int r;
550
551 assert(message);
552 assert(m);
553
554 /* Anyone can call this method */
555
556 r = sd_bus_message_read(message, "s", &name);
557 if (r < 0)
558 return r;
559
560 if (isempty(name)) {
561 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
562 pid_t pid;
563
564 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
565 if (r < 0)
566 return r;
567
568 r = sd_bus_creds_get_pid(creds, &pid);
569 if (r < 0)
570 return r;
571
572 u = manager_get_unit_by_pid(m, pid);
573 if (!u)
574 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
575 } else {
576 r = manager_load_unit(m, name, NULL, error, &u);
577 if (r < 0)
578 return r;
579 }
580
581 r = mac_selinux_unit_access_check(u, message, "status", error);
582 if (r < 0)
583 return r;
584
585 path = unit_dbus_path(u);
586 if (!path)
587 return -ENOMEM;
588
589 return sd_bus_reply_method_return(message, "o", path);
590 }
591
592 static int method_start_unit_generic(sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
593 const char *name;
594 Unit *u;
595 int r;
596
597 assert(message);
598 assert(m);
599
600 r = sd_bus_message_read(message, "s", &name);
601 if (r < 0)
602 return r;
603
604 r = manager_load_unit(m, name, NULL, error, &u);
605 if (r < 0)
606 return r;
607
608 return bus_unit_method_start_generic(message, u, job_type, reload_if_possible, error);
609 }
610
611 static int method_start_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
612 return method_start_unit_generic(message, userdata, JOB_START, false, error);
613 }
614
615 static int method_stop_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
616 return method_start_unit_generic(message, userdata, JOB_STOP, false, error);
617 }
618
619 static int method_reload_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
620 return method_start_unit_generic(message, userdata, JOB_RELOAD, false, error);
621 }
622
623 static int method_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
624 return method_start_unit_generic(message, userdata, JOB_RESTART, false, error);
625 }
626
627 static int method_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
628 return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, false, error);
629 }
630
631 static int method_reload_or_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
632 return method_start_unit_generic(message, userdata, JOB_RESTART, true, error);
633 }
634
635 static int method_reload_or_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
636 return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, true, error);
637 }
638
639 static int method_start_unit_replace(sd_bus_message *message, void *userdata, sd_bus_error *error) {
640 Manager *m = userdata;
641 const char *old_name;
642 Unit *u;
643 int r;
644
645 assert(message);
646 assert(m);
647
648 r = sd_bus_message_read(message, "s", &old_name);
649 if (r < 0)
650 return r;
651
652 u = manager_get_unit(m, old_name);
653 if (!u || !u->job || u->job->type != JOB_START)
654 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
655
656 return method_start_unit_generic(message, m, JOB_START, false, error);
657 }
658
659 static int method_kill_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
660 Manager *m = userdata;
661 const char *name;
662 Unit *u;
663 int r;
664
665 assert(message);
666 assert(m);
667
668 r = sd_bus_message_read(message, "s", &name);
669 if (r < 0)
670 return r;
671
672 u = manager_get_unit(m, name);
673 if (!u)
674 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
675
676 return bus_unit_method_kill(message, u, error);
677 }
678
679 static int method_reset_failed_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
680 Manager *m = userdata;
681 const char *name;
682 Unit *u;
683 int r;
684
685 assert(message);
686 assert(m);
687
688 r = sd_bus_message_read(message, "s", &name);
689 if (r < 0)
690 return r;
691
692 u = manager_get_unit(m, name);
693 if (!u)
694 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
695
696 return bus_unit_method_reset_failed(message, u, error);
697 }
698
699 static int method_set_unit_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
700 Manager *m = userdata;
701 const char *name;
702 Unit *u;
703 int r;
704
705 assert(message);
706 assert(m);
707
708 r = sd_bus_message_read(message, "s", &name);
709 if (r < 0)
710 return r;
711
712 r = manager_load_unit(m, name, NULL, error, &u);
713 if (r < 0)
714 return r;
715
716 r = bus_unit_check_load_state(u, error);
717 if (r < 0)
718 return r;
719
720 return bus_unit_method_set_properties(message, u, error);
721 }
722
723 static int method_ref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
724 Manager *m = userdata;
725 const char *name;
726 Unit *u;
727 int r;
728
729 assert(message);
730 assert(m);
731
732 r = sd_bus_message_read(message, "s", &name);
733 if (r < 0)
734 return r;
735
736 r = manager_load_unit(m, name, NULL, error, &u);
737 if (r < 0)
738 return r;
739
740 r = bus_unit_check_load_state(u, error);
741 if (r < 0)
742 return r;
743
744 return bus_unit_method_ref(message, u, error);
745 }
746
747 static int method_unref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
748 Manager *m = userdata;
749 const char *name;
750 Unit *u;
751 int r;
752
753 assert(message);
754 assert(m);
755
756 r = sd_bus_message_read(message, "s", &name);
757 if (r < 0)
758 return r;
759
760 r = manager_load_unit(m, name, NULL, error, &u);
761 if (r < 0)
762 return r;
763
764 r = bus_unit_check_load_state(u, error);
765 if (r < 0)
766 return r;
767
768 return bus_unit_method_unref(message, u, error);
769 }
770
771 static int reply_unit_info(sd_bus_message *reply, Unit *u) {
772 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
773 Unit *following;
774
775 following = unit_following(u);
776
777 unit_path = unit_dbus_path(u);
778 if (!unit_path)
779 return -ENOMEM;
780
781 if (u->job) {
782 job_path = job_dbus_path(u->job);
783 if (!job_path)
784 return -ENOMEM;
785 }
786
787 return sd_bus_message_append(
788 reply, "(ssssssouso)",
789 u->id,
790 unit_description(u),
791 unit_load_state_to_string(u->load_state),
792 unit_active_state_to_string(unit_active_state(u)),
793 unit_sub_state_to_string(u),
794 following ? following->id : "",
795 unit_path,
796 u->job ? u->job->id : 0,
797 u->job ? job_type_to_string(u->job->type) : "",
798 job_path ? job_path : "/");
799 }
800
801 static int method_list_units_by_names(sd_bus_message *message, void *userdata, sd_bus_error *error) {
802 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
803 Manager *m = userdata;
804 int r;
805 char **unit;
806 _cleanup_strv_free_ char **units = NULL;
807
808 assert(message);
809 assert(m);
810
811 r = sd_bus_message_read_strv(message, &units);
812 if (r < 0)
813 return r;
814
815 r = sd_bus_message_new_method_return(message, &reply);
816 if (r < 0)
817 return r;
818
819 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
820 if (r < 0)
821 return r;
822
823 STRV_FOREACH(unit, units) {
824 Unit *u;
825
826 if (!unit_name_is_valid(*unit, UNIT_NAME_ANY))
827 continue;
828
829 r = manager_load_unit(m, *unit, NULL, error, &u);
830 if (r < 0)
831 return r;
832
833 r = reply_unit_info(reply, u);
834 if (r < 0)
835 return r;
836 }
837
838 r = sd_bus_message_close_container(reply);
839 if (r < 0)
840 return r;
841
842 return sd_bus_send(NULL, reply, NULL);
843 }
844
845 static int method_get_unit_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
846 Manager *m = userdata;
847 const char *name;
848 Unit *u;
849 int r;
850
851 assert(message);
852 assert(m);
853
854 r = sd_bus_message_read(message, "s", &name);
855 if (r < 0)
856 return r;
857
858 u = manager_get_unit(m, name);
859 if (!u)
860 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
861
862 return bus_unit_method_get_processes(message, u, error);
863 }
864
865 static int transient_unit_from_message(
866 Manager *m,
867 sd_bus_message *message,
868 const char *name,
869 Unit **unit,
870 sd_bus_error *error) {
871
872 UnitType t;
873 Unit *u;
874 int r;
875
876 assert(m);
877 assert(message);
878 assert(name);
879
880 t = unit_name_to_type(name);
881 if (t < 0)
882 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name or type.");
883
884 if (!unit_vtable[t]->can_transient)
885 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
886
887 r = manager_load_unit(m, name, NULL, error, &u);
888 if (r < 0)
889 return r;
890
891 if (!unit_is_pristine(u))
892 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
893
894 /* OK, the unit failed to load and is unreferenced, now let's
895 * fill in the transient data instead */
896 r = unit_make_transient(u);
897 if (r < 0)
898 return r;
899
900 /* Set our properties */
901 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
902 if (r < 0)
903 return r;
904
905 /* If the client asked for it, automatically add a reference to this unit. */
906 if (u->bus_track_add) {
907 r = bus_unit_track_add_sender(u, message);
908 if (r < 0)
909 return log_error_errno(r, "Failed to watch sender: %m");
910 }
911
912 /* Now load the missing bits of the unit we just created */
913 unit_add_to_load_queue(u);
914 manager_dispatch_load_queue(m);
915
916 *unit = u;
917
918 return 0;
919 }
920
921 static int transient_aux_units_from_message(
922 Manager *m,
923 sd_bus_message *message,
924 sd_bus_error *error) {
925
926 int r;
927
928 assert(m);
929 assert(message);
930
931 r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
932 if (r < 0)
933 return r;
934
935 while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
936 const char *name = NULL;
937 Unit *u;
938
939 r = sd_bus_message_read(message, "s", &name);
940 if (r < 0)
941 return r;
942
943 r = transient_unit_from_message(m, message, name, &u, error);
944 if (r < 0)
945 return r;
946
947 r = sd_bus_message_exit_container(message);
948 if (r < 0)
949 return r;
950 }
951 if (r < 0)
952 return r;
953
954 r = sd_bus_message_exit_container(message);
955 if (r < 0)
956 return r;
957
958 return 0;
959 }
960
961 static int method_start_transient_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
962 const char *name, *smode;
963 Manager *m = userdata;
964 JobMode mode;
965 Unit *u;
966 int r;
967
968 assert(message);
969 assert(m);
970
971 r = mac_selinux_access_check(message, "start", error);
972 if (r < 0)
973 return r;
974
975 r = sd_bus_message_read(message, "ss", &name, &smode);
976 if (r < 0)
977 return r;
978
979 mode = job_mode_from_string(smode);
980 if (mode < 0)
981 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
982
983 r = bus_verify_manage_units_async(m, message, error);
984 if (r < 0)
985 return r;
986 if (r == 0)
987 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
988
989 r = transient_unit_from_message(m, message, name, &u, error);
990 if (r < 0)
991 return r;
992
993 r = transient_aux_units_from_message(m, message, error);
994 if (r < 0)
995 return r;
996
997 /* Finally, start it */
998 return bus_unit_queue_job(message, u, JOB_START, mode, false, error);
999 }
1000
1001 static int method_get_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1002 _cleanup_free_ char *path = NULL;
1003 Manager *m = userdata;
1004 uint32_t id;
1005 Job *j;
1006 int r;
1007
1008 assert(message);
1009 assert(m);
1010
1011 /* Anyone can call this method */
1012
1013 r = sd_bus_message_read(message, "u", &id);
1014 if (r < 0)
1015 return r;
1016
1017 j = manager_get_job(m, id);
1018 if (!j)
1019 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
1020
1021 r = mac_selinux_unit_access_check(j->unit, message, "status", error);
1022 if (r < 0)
1023 return r;
1024
1025 path = job_dbus_path(j);
1026 if (!path)
1027 return -ENOMEM;
1028
1029 return sd_bus_reply_method_return(message, "o", path);
1030 }
1031
1032 static int method_cancel_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1033 Manager *m = userdata;
1034 uint32_t id;
1035 Job *j;
1036 int r;
1037
1038 assert(message);
1039 assert(m);
1040
1041 r = sd_bus_message_read(message, "u", &id);
1042 if (r < 0)
1043 return r;
1044
1045 j = manager_get_job(m, id);
1046 if (!j)
1047 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
1048
1049 return bus_job_method_cancel(message, j, error);
1050 }
1051
1052 static int method_clear_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1053 Manager *m = userdata;
1054 int r;
1055
1056 assert(message);
1057 assert(m);
1058
1059 r = mac_selinux_access_check(message, "reload", error);
1060 if (r < 0)
1061 return r;
1062
1063 r = bus_verify_manage_units_async(m, message, error);
1064 if (r < 0)
1065 return r;
1066 if (r == 0)
1067 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1068
1069 manager_clear_jobs(m);
1070
1071 return sd_bus_reply_method_return(message, NULL);
1072 }
1073
1074 static int method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1075 Manager *m = userdata;
1076 int r;
1077
1078 assert(message);
1079 assert(m);
1080
1081 r = mac_selinux_access_check(message, "reload", error);
1082 if (r < 0)
1083 return r;
1084
1085 r = bus_verify_manage_units_async(m, message, error);
1086 if (r < 0)
1087 return r;
1088 if (r == 0)
1089 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1090
1091 manager_reset_failed(m);
1092
1093 return sd_bus_reply_method_return(message, NULL);
1094 }
1095
1096 static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
1097 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1098 Manager *m = userdata;
1099 const char *k;
1100 Iterator i;
1101 Unit *u;
1102 int r;
1103
1104 assert(message);
1105 assert(m);
1106
1107 /* Anyone can call this method */
1108
1109 r = mac_selinux_access_check(message, "status", error);
1110 if (r < 0)
1111 return r;
1112
1113 r = sd_bus_message_new_method_return(message, &reply);
1114 if (r < 0)
1115 return r;
1116
1117 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
1118 if (r < 0)
1119 return r;
1120
1121 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
1122 if (k != u->id)
1123 continue;
1124
1125 if (!strv_isempty(states) &&
1126 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
1127 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
1128 !strv_contains(states, unit_sub_state_to_string(u)))
1129 continue;
1130
1131 if (!strv_isempty(patterns) &&
1132 !strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
1133 continue;
1134
1135 r = reply_unit_info(reply, u);
1136 if (r < 0)
1137 return r;
1138 }
1139
1140 r = sd_bus_message_close_container(reply);
1141 if (r < 0)
1142 return r;
1143
1144 return sd_bus_send(NULL, reply, NULL);
1145 }
1146
1147 static int method_list_units(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1148 return list_units_filtered(message, userdata, error, NULL, NULL);
1149 }
1150
1151 static int method_list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1152 _cleanup_strv_free_ char **states = NULL;
1153 int r;
1154
1155 r = sd_bus_message_read_strv(message, &states);
1156 if (r < 0)
1157 return r;
1158
1159 return list_units_filtered(message, userdata, error, states, NULL);
1160 }
1161
1162 static int method_list_units_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1163 _cleanup_strv_free_ char **states = NULL;
1164 _cleanup_strv_free_ char **patterns = NULL;
1165 int r;
1166
1167 r = sd_bus_message_read_strv(message, &states);
1168 if (r < 0)
1169 return r;
1170
1171 r = sd_bus_message_read_strv(message, &patterns);
1172 if (r < 0)
1173 return r;
1174
1175 return list_units_filtered(message, userdata, error, states, patterns);
1176 }
1177
1178 static int method_list_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1179 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1180 Manager *m = userdata;
1181 Iterator i;
1182 Job *j;
1183 int r;
1184
1185 assert(message);
1186 assert(m);
1187
1188 /* Anyone can call this method */
1189
1190 r = mac_selinux_access_check(message, "status", error);
1191 if (r < 0)
1192 return r;
1193
1194 r = sd_bus_message_new_method_return(message, &reply);
1195 if (r < 0)
1196 return r;
1197
1198 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
1199 if (r < 0)
1200 return r;
1201
1202 HASHMAP_FOREACH(j, m->jobs, i) {
1203 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
1204
1205 job_path = job_dbus_path(j);
1206 if (!job_path)
1207 return -ENOMEM;
1208
1209 unit_path = unit_dbus_path(j->unit);
1210 if (!unit_path)
1211 return -ENOMEM;
1212
1213 r = sd_bus_message_append(
1214 reply, "(usssoo)",
1215 j->id,
1216 j->unit->id,
1217 job_type_to_string(j->type),
1218 job_state_to_string(j->state),
1219 job_path,
1220 unit_path);
1221 if (r < 0)
1222 return r;
1223 }
1224
1225 r = sd_bus_message_close_container(reply);
1226 if (r < 0)
1227 return r;
1228
1229 return sd_bus_send(NULL, reply, NULL);
1230 }
1231
1232 static int method_subscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1233 Manager *m = userdata;
1234 int r;
1235
1236 assert(message);
1237 assert(m);
1238
1239 /* Anyone can call this method */
1240
1241 r = mac_selinux_access_check(message, "status", error);
1242 if (r < 0)
1243 return r;
1244
1245 if (sd_bus_message_get_bus(message) == m->api_bus) {
1246
1247 /* Note that direct bus connection subscribe by
1248 * default, we only track peers on the API bus here */
1249
1250 if (!m->subscribed) {
1251 r = sd_bus_track_new(sd_bus_message_get_bus(message), &m->subscribed, NULL, NULL);
1252 if (r < 0)
1253 return r;
1254 }
1255
1256 r = sd_bus_track_add_sender(m->subscribed, message);
1257 if (r < 0)
1258 return r;
1259 if (r == 0)
1260 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1261 }
1262
1263 return sd_bus_reply_method_return(message, NULL);
1264 }
1265
1266 static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1267 Manager *m = userdata;
1268 int r;
1269
1270 assert(message);
1271 assert(m);
1272
1273 /* Anyone can call this method */
1274
1275 r = mac_selinux_access_check(message, "status", error);
1276 if (r < 0)
1277 return r;
1278
1279 if (sd_bus_message_get_bus(message) == m->api_bus) {
1280 r = sd_bus_track_remove_sender(m->subscribed, message);
1281 if (r < 0)
1282 return r;
1283 if (r == 0)
1284 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1285 }
1286
1287 return sd_bus_reply_method_return(message, NULL);
1288 }
1289
1290 static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1291 _cleanup_free_ char *dump = NULL;
1292 _cleanup_fclose_ FILE *f = NULL;
1293 Manager *m = userdata;
1294 size_t size;
1295 int r;
1296
1297 assert(message);
1298 assert(m);
1299
1300 /* Anyone can call this method */
1301
1302 r = mac_selinux_access_check(message, "status", error);
1303 if (r < 0)
1304 return r;
1305
1306 f = open_memstream(&dump, &size);
1307 if (!f)
1308 return -ENOMEM;
1309
1310 manager_dump_units(m, f, NULL);
1311 manager_dump_jobs(m, f, NULL);
1312
1313 r = fflush_and_check(f);
1314 if (r < 0)
1315 return r;
1316
1317 return sd_bus_reply_method_return(message, "s", dump);
1318 }
1319
1320 static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1321 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
1322 }
1323
1324 static int verify_run_space(const char *message, sd_bus_error *error) {
1325 struct statvfs svfs;
1326 uint64_t available;
1327
1328 if (statvfs("/run/systemd", &svfs) < 0)
1329 return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m");
1330
1331 available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
1332
1333 if (available < RELOAD_DISK_SPACE_MIN) {
1334 char fb_available[FORMAT_BYTES_MAX], fb_need[FORMAT_BYTES_MAX];
1335 return sd_bus_error_setf(error,
1336 BUS_ERROR_DISK_FULL,
1337 "%s, not enough space available on /run/systemd. "
1338 "Currently, %s are free, but a safety buffer of %s is enforced.",
1339 message,
1340 format_bytes(fb_available, sizeof(fb_available), available),
1341 format_bytes(fb_need, sizeof(fb_need), RELOAD_DISK_SPACE_MIN));
1342 }
1343
1344 return 0;
1345 }
1346
1347 int verify_run_space_and_log(const char *message) {
1348 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1349 int r;
1350
1351 r = verify_run_space(message, &error);
1352 if (r < 0)
1353 log_error_errno(r, "%s", bus_error_message(&error, r));
1354
1355 return r;
1356 }
1357
1358 static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1359 Manager *m = userdata;
1360 int r;
1361
1362 assert(message);
1363 assert(m);
1364
1365 r = verify_run_space("Refusing to reload", error);
1366 if (r < 0)
1367 return r;
1368
1369 r = mac_selinux_access_check(message, "reload", error);
1370 if (r < 0)
1371 return r;
1372
1373 r = bus_verify_reload_daemon_async(m, message, error);
1374 if (r < 0)
1375 return r;
1376 if (r == 0)
1377 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1378
1379 /* Instead of sending the reply back right away, we just
1380 * remember that we need to and then send it after the reload
1381 * is finished. That way the caller knows when the reload
1382 * finished. */
1383
1384 assert(!m->queued_message);
1385 r = sd_bus_message_new_method_return(message, &m->queued_message);
1386 if (r < 0)
1387 return r;
1388
1389 m->exit_code = MANAGER_RELOAD;
1390
1391 return 1;
1392 }
1393
1394 static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1395 Manager *m = userdata;
1396 int r;
1397
1398 assert(message);
1399 assert(m);
1400
1401 r = verify_run_space("Refusing to reexecute", error);
1402 if (r < 0)
1403 return r;
1404
1405 r = mac_selinux_access_check(message, "reload", error);
1406 if (r < 0)
1407 return r;
1408
1409 r = bus_verify_reload_daemon_async(m, message, error);
1410 if (r < 0)
1411 return r;
1412 if (r == 0)
1413 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1414
1415 /* We don't send a reply back here, the client should
1416 * just wait for us disconnecting. */
1417
1418 m->exit_code = MANAGER_REEXECUTE;
1419 return 1;
1420 }
1421
1422 static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1423 Manager *m = userdata;
1424 int r;
1425
1426 assert(message);
1427 assert(m);
1428
1429 r = mac_selinux_access_check(message, "halt", error);
1430 if (r < 0)
1431 return r;
1432
1433 /* Exit() (in contrast to SetExitCode()) is actually allowed even if
1434 * we are running on the host. It will fall back on reboot() in
1435 * systemd-shutdown if it cannot do the exit() because it isn't a
1436 * container. */
1437
1438 m->exit_code = MANAGER_EXIT;
1439
1440 return sd_bus_reply_method_return(message, NULL);
1441 }
1442
1443 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1444 Manager *m = userdata;
1445 int r;
1446
1447 assert(message);
1448 assert(m);
1449
1450 r = mac_selinux_access_check(message, "reboot", error);
1451 if (r < 0)
1452 return r;
1453
1454 if (!MANAGER_IS_SYSTEM(m))
1455 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1456
1457 m->exit_code = MANAGER_REBOOT;
1458
1459 return sd_bus_reply_method_return(message, NULL);
1460 }
1461
1462 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1463 Manager *m = userdata;
1464 int r;
1465
1466 assert(message);
1467 assert(m);
1468
1469 r = mac_selinux_access_check(message, "halt", error);
1470 if (r < 0)
1471 return r;
1472
1473 if (!MANAGER_IS_SYSTEM(m))
1474 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1475
1476 m->exit_code = MANAGER_POWEROFF;
1477
1478 return sd_bus_reply_method_return(message, NULL);
1479 }
1480
1481 static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1482 Manager *m = userdata;
1483 int r;
1484
1485 assert(message);
1486 assert(m);
1487
1488 r = mac_selinux_access_check(message, "halt", error);
1489 if (r < 0)
1490 return r;
1491
1492 if (!MANAGER_IS_SYSTEM(m))
1493 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1494
1495 m->exit_code = MANAGER_HALT;
1496
1497 return sd_bus_reply_method_return(message, NULL);
1498 }
1499
1500 static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1501 Manager *m = userdata;
1502 int r;
1503
1504 assert(message);
1505 assert(m);
1506
1507 r = mac_selinux_access_check(message, "reboot", error);
1508 if (r < 0)
1509 return r;
1510
1511 if (!MANAGER_IS_SYSTEM(m))
1512 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1513
1514 m->exit_code = MANAGER_KEXEC;
1515
1516 return sd_bus_reply_method_return(message, NULL);
1517 }
1518
1519 static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1520 char *ri = NULL, *rt = NULL;
1521 const char *root, *init;
1522 Manager *m = userdata;
1523 struct statvfs svfs;
1524 uint64_t available;
1525 int r;
1526
1527 assert(message);
1528 assert(m);
1529
1530 if (statvfs("/run/systemd", &svfs) < 0)
1531 return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m");
1532
1533 available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
1534
1535 if (available < RELOAD_DISK_SPACE_MIN) {
1536 char fb_available[FORMAT_BYTES_MAX], fb_need[FORMAT_BYTES_MAX];
1537 log_warning("Dangerously low amount of free space on /run/systemd, root switching operation might not complete successfuly. "
1538 "Currently, %s are free, but %s are suggested. Proceeding anyway.",
1539 format_bytes(fb_available, sizeof(fb_available), available),
1540 format_bytes(fb_need, sizeof(fb_need), RELOAD_DISK_SPACE_MIN));
1541 }
1542
1543 r = mac_selinux_access_check(message, "reboot", error);
1544 if (r < 0)
1545 return r;
1546
1547 if (!MANAGER_IS_SYSTEM(m))
1548 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1549
1550 r = sd_bus_message_read(message, "ss", &root, &init);
1551 if (r < 0)
1552 return r;
1553
1554 if (isempty(root))
1555 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory may not be the empty string.");
1556 if (!path_is_absolute(root))
1557 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root path '%s' is not absolute.", root);
1558 if (path_equal(root, "/"))
1559 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory cannot be the old root directory.");
1560
1561 /* Safety check */
1562 if (isempty(init)) {
1563 r = path_is_os_tree(root);
1564 if (r < 0)
1565 return sd_bus_error_set_errnof(error, r, "Failed to determine whether root path '%s' contains an OS tree: %m", root);
1566 if (r == 0)
1567 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.", root);
1568 } else {
1569 _cleanup_free_ char *chased = NULL;
1570
1571 if (!path_is_absolute(init))
1572 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path to init binary '%s' not absolute.", init);
1573
1574 r = chase_symlinks(init, root, CHASE_PREFIX_ROOT, &chased);
1575 if (r < 0)
1576 return sd_bus_error_set_errnof(error, r, "Could not resolve init executable %s: %m", init);
1577
1578 if (laccess(chased, X_OK) < 0) {
1579 if (errno == EACCES)
1580 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Init binary %s is not executable.", init);
1581
1582 return sd_bus_error_set_errnof(error, r, "Could not check whether init binary %s is executable: %m", init);
1583 }
1584 }
1585
1586 rt = strdup(root);
1587 if (!rt)
1588 return -ENOMEM;
1589
1590 if (!isempty(init)) {
1591 ri = strdup(init);
1592 if (!ri) {
1593 free(rt);
1594 return -ENOMEM;
1595 }
1596 }
1597
1598 free(m->switch_root);
1599 m->switch_root = rt;
1600
1601 free(m->switch_root_init);
1602 m->switch_root_init = ri;
1603
1604 m->exit_code = MANAGER_SWITCH_ROOT;
1605
1606 return sd_bus_reply_method_return(message, NULL);
1607 }
1608
1609 static int method_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1610 _cleanup_strv_free_ char **plus = NULL;
1611 Manager *m = userdata;
1612 int r;
1613
1614 assert(message);
1615 assert(m);
1616
1617 r = mac_selinux_access_check(message, "reload", error);
1618 if (r < 0)
1619 return r;
1620
1621 r = sd_bus_message_read_strv(message, &plus);
1622 if (r < 0)
1623 return r;
1624 if (!strv_env_is_valid(plus))
1625 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1626
1627 r = bus_verify_set_environment_async(m, message, error);
1628 if (r < 0)
1629 return r;
1630 if (r == 0)
1631 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1632
1633 r = manager_environment_add(m, NULL, plus);
1634 if (r < 0)
1635 return r;
1636
1637 return sd_bus_reply_method_return(message, NULL);
1638 }
1639
1640 static int method_unset_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1641 _cleanup_strv_free_ char **minus = NULL;
1642 Manager *m = userdata;
1643 int r;
1644
1645 assert(message);
1646 assert(m);
1647
1648 r = mac_selinux_access_check(message, "reload", error);
1649 if (r < 0)
1650 return r;
1651
1652 r = sd_bus_message_read_strv(message, &minus);
1653 if (r < 0)
1654 return r;
1655
1656 if (!strv_env_name_or_assignment_is_valid(minus))
1657 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1658
1659 r = bus_verify_set_environment_async(m, message, error);
1660 if (r < 0)
1661 return r;
1662 if (r == 0)
1663 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1664
1665 r = manager_environment_add(m, minus, NULL);
1666 if (r < 0)
1667 return r;
1668
1669 return sd_bus_reply_method_return(message, NULL);
1670 }
1671
1672 static int method_unset_and_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1673 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1674 Manager *m = userdata;
1675 int r;
1676
1677 assert(message);
1678 assert(m);
1679
1680 r = mac_selinux_access_check(message, "reload", error);
1681 if (r < 0)
1682 return r;
1683
1684 r = sd_bus_message_read_strv(message, &minus);
1685 if (r < 0)
1686 return r;
1687
1688 r = sd_bus_message_read_strv(message, &plus);
1689 if (r < 0)
1690 return r;
1691
1692 if (!strv_env_name_or_assignment_is_valid(minus))
1693 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1694 if (!strv_env_is_valid(plus))
1695 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1696
1697 r = bus_verify_set_environment_async(m, message, error);
1698 if (r < 0)
1699 return r;
1700 if (r == 0)
1701 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1702
1703 r = manager_environment_add(m, minus, plus);
1704 if (r < 0)
1705 return r;
1706
1707 return sd_bus_reply_method_return(message, NULL);
1708 }
1709
1710 static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1711 Manager *m = userdata;
1712 uint8_t code;
1713 int r;
1714
1715 assert(message);
1716 assert(m);
1717
1718 r = mac_selinux_access_check(message, "exit", error);
1719 if (r < 0)
1720 return r;
1721
1722 r = sd_bus_message_read_basic(message, 'y', &code);
1723 if (r < 0)
1724 return r;
1725
1726 if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0)
1727 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "ExitCode can only be set for user service managers or in containers.");
1728
1729 m->return_value = code;
1730
1731 return sd_bus_reply_method_return(message, NULL);
1732 }
1733
1734 static int method_lookup_dynamic_user_by_name(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1735 Manager *m = userdata;
1736 const char *name;
1737 uid_t uid;
1738 int r;
1739
1740 assert(message);
1741 assert(m);
1742
1743 r = sd_bus_message_read_basic(message, 's', &name);
1744 if (r < 0)
1745 return r;
1746
1747 if (!MANAGER_IS_SYSTEM(m))
1748 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
1749 if (!valid_user_group_name(name))
1750 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User name invalid: %s", name);
1751
1752 r = dynamic_user_lookup_name(m, name, &uid);
1753 if (r == -ESRCH)
1754 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER, "Dynamic user %s does not exist.", name);
1755 if (r < 0)
1756 return r;
1757
1758 return sd_bus_reply_method_return(message, "u", (uint32_t) uid);
1759 }
1760
1761 static int method_lookup_dynamic_user_by_uid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1762 _cleanup_free_ char *name = NULL;
1763 Manager *m = userdata;
1764 uid_t uid;
1765 int r;
1766
1767 assert(message);
1768 assert(m);
1769
1770 assert_cc(sizeof(uid) == sizeof(uint32_t));
1771 r = sd_bus_message_read_basic(message, 'u', &uid);
1772 if (r < 0)
1773 return r;
1774
1775 if (!MANAGER_IS_SYSTEM(m))
1776 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
1777 if (!uid_is_valid(uid))
1778 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User ID invalid: " UID_FMT, uid);
1779
1780 r = dynamic_user_lookup_uid(m, uid, &name);
1781 if (r == -ESRCH)
1782 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER, "Dynamic user ID " UID_FMT " does not exist.", uid);
1783 if (r < 0)
1784 return r;
1785
1786 return sd_bus_reply_method_return(message, "s", name);
1787 }
1788
1789 static int list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
1790 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1791 Manager *m = userdata;
1792 UnitFileList *item;
1793 Hashmap *h;
1794 Iterator i;
1795 int r;
1796
1797 assert(message);
1798 assert(m);
1799
1800 /* Anyone can call this method */
1801
1802 r = mac_selinux_access_check(message, "status", error);
1803 if (r < 0)
1804 return r;
1805
1806 r = sd_bus_message_new_method_return(message, &reply);
1807 if (r < 0)
1808 return r;
1809
1810 h = hashmap_new(&string_hash_ops);
1811 if (!h)
1812 return -ENOMEM;
1813
1814 r = unit_file_get_list(m->unit_file_scope, NULL, h, states, patterns);
1815 if (r < 0)
1816 goto fail;
1817
1818 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1819 if (r < 0)
1820 goto fail;
1821
1822 HASHMAP_FOREACH(item, h, i) {
1823
1824 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1825 if (r < 0)
1826 goto fail;
1827 }
1828
1829 unit_file_list_free(h);
1830
1831 r = sd_bus_message_close_container(reply);
1832 if (r < 0)
1833 return r;
1834
1835 return sd_bus_send(NULL, reply, NULL);
1836
1837 fail:
1838 unit_file_list_free(h);
1839 return r;
1840 }
1841
1842 static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1843 return list_unit_files_by_patterns(message, userdata, error, NULL, NULL);
1844 }
1845
1846 static int method_list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1847 _cleanup_strv_free_ char **states = NULL;
1848 _cleanup_strv_free_ char **patterns = NULL;
1849 int r;
1850
1851 r = sd_bus_message_read_strv(message, &states);
1852 if (r < 0)
1853 return r;
1854
1855 r = sd_bus_message_read_strv(message, &patterns);
1856 if (r < 0)
1857 return r;
1858
1859 return list_unit_files_by_patterns(message, userdata, error, states, patterns);
1860 }
1861
1862 static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1863 Manager *m = userdata;
1864 const char *name;
1865 UnitFileState state;
1866 int r;
1867
1868 assert(message);
1869 assert(m);
1870
1871 /* Anyone can call this method */
1872
1873 r = mac_selinux_access_check(message, "status", error);
1874 if (r < 0)
1875 return r;
1876
1877 r = sd_bus_message_read(message, "s", &name);
1878 if (r < 0)
1879 return r;
1880
1881 r = unit_file_get_state(m->unit_file_scope, NULL, name, &state);
1882 if (r < 0)
1883 return r;
1884
1885 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1886 }
1887
1888 static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1889 _cleanup_free_ char *default_target = NULL;
1890 Manager *m = userdata;
1891 int r;
1892
1893 assert(message);
1894 assert(m);
1895
1896 /* Anyone can call this method */
1897
1898 r = mac_selinux_access_check(message, "status", error);
1899 if (r < 0)
1900 return r;
1901
1902 r = unit_file_get_default(m->unit_file_scope, NULL, &default_target);
1903 if (r < 0)
1904 return r;
1905
1906 return sd_bus_reply_method_return(message, "s", default_target);
1907 }
1908
1909 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1910 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
1911 int r;
1912
1913 assert(bus);
1914
1915 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1916 if (r < 0)
1917 return r;
1918
1919 return sd_bus_send(bus, message, NULL);
1920 }
1921
1922 /* Create an error reply, using the error information from changes[]
1923 * if possible, and fall back to generating an error from error code c.
1924 * The error message only describes the first error.
1925 *
1926 * Coordinate with unit_file_dump_changes() in install.c.
1927 */
1928 static int install_error(
1929 sd_bus_error *error,
1930 int c,
1931 UnitFileChange *changes,
1932 unsigned n_changes) {
1933 int r;
1934 unsigned i;
1935
1936 for (i = 0; i < n_changes; i++)
1937
1938 switch(changes[i].type) {
1939
1940 case 0 ... INT_MAX:
1941 continue;
1942
1943 case -EEXIST:
1944 if (changes[i].source)
1945 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
1946 "File %s already exists and is a symlink to %s.",
1947 changes[i].path, changes[i].source);
1948 else
1949 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
1950 "File %s already exists.",
1951 changes[i].path);
1952 goto found;
1953
1954 case -ERFKILL:
1955 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED,
1956 "Unit file %s is masked.", changes[i].path);
1957 goto found;
1958
1959 case -EADDRNOTAVAIL:
1960 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED,
1961 "Unit %s is transient or generated.", changes[i].path);
1962 goto found;
1963
1964 case -ELOOP:
1965 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_LINKED,
1966 "Refusing to operate on linked unit file %s", changes[i].path);
1967 goto found;
1968
1969 case -ENOENT:
1970 r = sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit file %s does not exist.", changes[i].path);
1971 goto found;
1972
1973 default:
1974 r = sd_bus_error_set_errnof(error, changes[i].type, "File %s: %m", changes[i].path);
1975 goto found;
1976 }
1977
1978 r = c < 0 ? c : -EINVAL;
1979
1980 found:
1981 unit_file_changes_free(changes, n_changes);
1982 return r;
1983 }
1984
1985 static int reply_unit_file_changes_and_free(
1986 Manager *m,
1987 sd_bus_message *message,
1988 int carries_install_info,
1989 UnitFileChange *changes,
1990 unsigned n_changes,
1991 sd_bus_error *error) {
1992
1993 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1994 bool bad = false, good = false;
1995 unsigned i;
1996 int r;
1997
1998 if (unit_file_changes_have_modification(changes, n_changes)) {
1999 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
2000 if (r < 0)
2001 log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
2002 }
2003
2004 r = sd_bus_message_new_method_return(message, &reply);
2005 if (r < 0)
2006 goto fail;
2007
2008 if (carries_install_info >= 0) {
2009 r = sd_bus_message_append(reply, "b", carries_install_info);
2010 if (r < 0)
2011 goto fail;
2012 }
2013
2014 r = sd_bus_message_open_container(reply, 'a', "(sss)");
2015 if (r < 0)
2016 goto fail;
2017
2018 for (i = 0; i < n_changes; i++) {
2019
2020 if (changes[i].type < 0) {
2021 bad = true;
2022 continue;
2023 }
2024
2025 r = sd_bus_message_append(
2026 reply, "(sss)",
2027 unit_file_change_type_to_string(changes[i].type),
2028 changes[i].path,
2029 changes[i].source);
2030 if (r < 0)
2031 goto fail;
2032
2033 good = true;
2034 }
2035
2036 /* If there was a failed change, and no successful change, then return the first failure as proper method call
2037 * error. */
2038 if (bad && !good)
2039 return install_error(error, 0, changes, n_changes);
2040
2041 r = sd_bus_message_close_container(reply);
2042 if (r < 0)
2043 goto fail;
2044
2045 unit_file_changes_free(changes, n_changes);
2046 return sd_bus_send(NULL, reply, NULL);
2047
2048 fail:
2049 unit_file_changes_free(changes, n_changes);
2050 return r;
2051 }
2052
2053 static int method_enable_unit_files_generic(
2054 sd_bus_message *message,
2055 Manager *m,
2056 int (*call)(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
2057 bool carries_install_info,
2058 sd_bus_error *error) {
2059
2060 _cleanup_strv_free_ char **l = NULL;
2061 UnitFileChange *changes = NULL;
2062 unsigned n_changes = 0;
2063 UnitFileFlags flags;
2064 int runtime, force, r;
2065
2066 assert(message);
2067 assert(m);
2068
2069 r = sd_bus_message_read_strv(message, &l);
2070 if (r < 0)
2071 return r;
2072
2073 r = sd_bus_message_read(message, "bb", &runtime, &force);
2074 if (r < 0)
2075 return r;
2076
2077 flags = unit_file_bools_to_flags(runtime, force);
2078
2079 r = bus_verify_manage_unit_files_async(m, message, error);
2080 if (r < 0)
2081 return r;
2082 if (r == 0)
2083 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2084
2085 r = call(m->unit_file_scope, flags, NULL, l, &changes, &n_changes);
2086 if (r < 0)
2087 return install_error(error, r, changes, n_changes);
2088
2089 return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error);
2090 }
2091
2092 static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2093 return method_enable_unit_files_generic(message, userdata, unit_file_enable, true, error);
2094 }
2095
2096 static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2097 return method_enable_unit_files_generic(message, userdata, unit_file_reenable, true, error);
2098 }
2099
2100 static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2101 return method_enable_unit_files_generic(message, userdata, unit_file_link, false, error);
2102 }
2103
2104 static int unit_file_preset_without_mode(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char **files, UnitFileChange **changes, unsigned *n_changes) {
2105 return unit_file_preset(scope, flags, root_dir, files, UNIT_FILE_PRESET_FULL, changes, n_changes);
2106 }
2107
2108 static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2109 return method_enable_unit_files_generic(message, userdata, unit_file_preset_without_mode, true, error);
2110 }
2111
2112 static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2113 return method_enable_unit_files_generic(message, userdata, unit_file_mask, false, error);
2114 }
2115
2116 static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2117
2118 _cleanup_strv_free_ char **l = NULL;
2119 UnitFileChange *changes = NULL;
2120 unsigned n_changes = 0;
2121 Manager *m = userdata;
2122 UnitFilePresetMode mm;
2123 int runtime, force, r;
2124 UnitFileFlags flags;
2125 const char *mode;
2126
2127 assert(message);
2128 assert(m);
2129
2130 r = sd_bus_message_read_strv(message, &l);
2131 if (r < 0)
2132 return r;
2133
2134 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
2135 if (r < 0)
2136 return r;
2137
2138 flags = unit_file_bools_to_flags(runtime, force);
2139
2140 if (isempty(mode))
2141 mm = UNIT_FILE_PRESET_FULL;
2142 else {
2143 mm = unit_file_preset_mode_from_string(mode);
2144 if (mm < 0)
2145 return -EINVAL;
2146 }
2147
2148 r = bus_verify_manage_unit_files_async(m, message, error);
2149 if (r < 0)
2150 return r;
2151 if (r == 0)
2152 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2153
2154 r = unit_file_preset(m->unit_file_scope, flags, NULL, l, mm, &changes, &n_changes);
2155 if (r < 0)
2156 return install_error(error, r, changes, n_changes);
2157
2158 return reply_unit_file_changes_and_free(m, message, r, changes, n_changes, error);
2159 }
2160
2161 static int method_disable_unit_files_generic(
2162 sd_bus_message *message,
2163 Manager *m,
2164 int (*call)(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
2165 sd_bus_error *error) {
2166
2167 _cleanup_strv_free_ char **l = NULL;
2168 UnitFileChange *changes = NULL;
2169 unsigned n_changes = 0;
2170 int r, runtime;
2171
2172 assert(message);
2173 assert(m);
2174
2175 r = sd_bus_message_read_strv(message, &l);
2176 if (r < 0)
2177 return r;
2178
2179 r = sd_bus_message_read(message, "b", &runtime);
2180 if (r < 0)
2181 return r;
2182
2183 r = bus_verify_manage_unit_files_async(m, message, error);
2184 if (r < 0)
2185 return r;
2186 if (r == 0)
2187 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2188
2189 r = call(m->unit_file_scope, runtime ? UNIT_FILE_RUNTIME : 0, NULL, l, &changes, &n_changes);
2190 if (r < 0)
2191 return install_error(error, r, changes, n_changes);
2192
2193 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
2194 }
2195
2196 static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2197 return method_disable_unit_files_generic(message, userdata, unit_file_disable, error);
2198 }
2199
2200 static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2201 return method_disable_unit_files_generic(message, userdata, unit_file_unmask, error);
2202 }
2203
2204 static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2205 _cleanup_strv_free_ char **l = NULL;
2206 UnitFileChange *changes = NULL;
2207 unsigned n_changes = 0;
2208 Manager *m = userdata;
2209 int r;
2210
2211 assert(message);
2212 assert(m);
2213
2214 r = sd_bus_message_read_strv(message, &l);
2215 if (r < 0)
2216 return r;
2217
2218 r = bus_verify_manage_unit_files_async(m, message, error);
2219 if (r < 0)
2220 return r;
2221 if (r == 0)
2222 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2223
2224 r = unit_file_revert(m->unit_file_scope, NULL, l, &changes, &n_changes);
2225 if (r < 0)
2226 return install_error(error, r, changes, n_changes);
2227
2228 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
2229 }
2230
2231 static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2232 UnitFileChange *changes = NULL;
2233 unsigned n_changes = 0;
2234 Manager *m = userdata;
2235 const char *name;
2236 int force, r;
2237
2238 assert(message);
2239 assert(m);
2240
2241 r = mac_selinux_access_check(message, "enable", error);
2242 if (r < 0)
2243 return r;
2244
2245 r = sd_bus_message_read(message, "sb", &name, &force);
2246 if (r < 0)
2247 return r;
2248
2249 r = bus_verify_manage_unit_files_async(m, message, error);
2250 if (r < 0)
2251 return r;
2252 if (r == 0)
2253 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2254
2255 r = unit_file_set_default(m->unit_file_scope, force ? UNIT_FILE_FORCE : 0, NULL, name, &changes, &n_changes);
2256 if (r < 0)
2257 return install_error(error, r, changes, n_changes);
2258
2259 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
2260 }
2261
2262 static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2263 UnitFileChange *changes = NULL;
2264 unsigned n_changes = 0;
2265 Manager *m = userdata;
2266 UnitFilePresetMode mm;
2267 const char *mode;
2268 UnitFileFlags flags;
2269 int force, runtime, r;
2270
2271 assert(message);
2272 assert(m);
2273
2274 r = mac_selinux_access_check(message, "enable", error);
2275 if (r < 0)
2276 return r;
2277
2278 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
2279 if (r < 0)
2280 return r;
2281
2282 flags = unit_file_bools_to_flags(runtime, force);
2283
2284 if (isempty(mode))
2285 mm = UNIT_FILE_PRESET_FULL;
2286 else {
2287 mm = unit_file_preset_mode_from_string(mode);
2288 if (mm < 0)
2289 return -EINVAL;
2290 }
2291
2292 r = bus_verify_manage_unit_files_async(m, message, error);
2293 if (r < 0)
2294 return r;
2295 if (r == 0)
2296 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2297
2298 r = unit_file_preset_all(m->unit_file_scope, flags, NULL, mm, &changes, &n_changes);
2299 if (r < 0)
2300 return install_error(error, r, changes, n_changes);
2301
2302 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
2303 }
2304
2305 static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2306 _cleanup_strv_free_ char **l = NULL;
2307 Manager *m = userdata;
2308 UnitFileChange *changes = NULL;
2309 unsigned n_changes = 0;
2310 int runtime, force, r;
2311 char *target, *type;
2312 UnitDependency dep;
2313 UnitFileFlags flags;
2314
2315 assert(message);
2316 assert(m);
2317
2318 r = bus_verify_manage_unit_files_async(m, message, error);
2319 if (r < 0)
2320 return r;
2321 if (r == 0)
2322 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
2323
2324 r = sd_bus_message_read_strv(message, &l);
2325 if (r < 0)
2326 return r;
2327
2328 r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
2329 if (r < 0)
2330 return r;
2331
2332 flags = unit_file_bools_to_flags(runtime, force);
2333
2334 dep = unit_dependency_from_string(type);
2335 if (dep < 0)
2336 return -EINVAL;
2337
2338 r = unit_file_add_dependency(m->unit_file_scope, flags, NULL, l, target, dep, &changes, &n_changes);
2339 if (r < 0)
2340 return install_error(error, r, changes, n_changes);
2341
2342 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
2343 }
2344
2345 static int method_get_unit_file_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2346 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
2347 UnitFileChange *changes = NULL;
2348 unsigned n_changes = 0, i;
2349 UnitFileFlags flags;
2350 const char *name;
2351 char **p;
2352 int runtime, r;
2353
2354 r = sd_bus_message_read(message, "sb", &name, &runtime);
2355 if (r < 0)
2356 return r;
2357
2358 r = sd_bus_message_new_method_return(message, &reply);
2359 if (r < 0)
2360 return r;
2361
2362 r = sd_bus_message_open_container(reply, SD_BUS_TYPE_ARRAY, "s");
2363 if (r < 0)
2364 return r;
2365
2366 p = STRV_MAKE(name);
2367 flags = UNIT_FILE_DRY_RUN |
2368 (runtime ? UNIT_FILE_RUNTIME : 0);
2369
2370 r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
2371 if (r < 0)
2372 return log_error_errno(r, "Failed to get file links for %s: %m", name);
2373
2374 for (i = 0; i < n_changes; i++)
2375 if (changes[i].type == UNIT_FILE_UNLINK) {
2376 r = sd_bus_message_append(reply, "s", changes[i].path);
2377 if (r < 0)
2378 return r;
2379 }
2380
2381 r = sd_bus_message_close_container(reply);
2382 if (r < 0)
2383 return r;
2384
2385 return sd_bus_send(NULL, reply, NULL);
2386 }
2387
2388 static int method_get_job_waiting(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2389 Manager *m = userdata;
2390 uint32_t id;
2391 Job *j;
2392 int r;
2393
2394 assert(message);
2395 assert(m);
2396
2397 r = sd_bus_message_read(message, "u", &id);
2398 if (r < 0)
2399 return r;
2400
2401 j = manager_get_job(m, id);
2402 if (!j)
2403 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
2404
2405 return bus_job_method_get_waiting_jobs(message, j, error);
2406 }
2407
2408 const sd_bus_vtable bus_manager_vtable[] = {
2409 SD_BUS_VTABLE_START(0),
2410
2411 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2412 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2413 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2414 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2415 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2416 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2417 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2418 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2419 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2420 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2421 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2422 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2423 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2424 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2425 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2426 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2427 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
2428 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
2429 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
2430 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
2431 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
2432 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
2433 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
2434 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
2435 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
2436 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
2437 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
2438 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
2439 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST),
2440 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
2441 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
2442 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
2443 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
2444 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
2445 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
2446 SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0),
2447 SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec, offsetof(Manager, default_timer_accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2448 SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2449 SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2450 SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
2451 SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
2452 SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* obsolete alias name */
2453 SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
2454 SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2455 SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2456 SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, default_memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2457 SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, default_tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
2458 SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
2459 SD_BUS_PROPERTY("DefaultLimitCPUSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
2460 SD_BUS_PROPERTY("DefaultLimitFSIZE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
2461 SD_BUS_PROPERTY("DefaultLimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
2462 SD_BUS_PROPERTY("DefaultLimitDATA", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
2463 SD_BUS_PROPERTY("DefaultLimitDATASoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
2464 SD_BUS_PROPERTY("DefaultLimitSTACK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
2465 SD_BUS_PROPERTY("DefaultLimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
2466 SD_BUS_PROPERTY("DefaultLimitCORE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
2467 SD_BUS_PROPERTY("DefaultLimitCORESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
2468 SD_BUS_PROPERTY("DefaultLimitRSS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
2469 SD_BUS_PROPERTY("DefaultLimitRSSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
2470 SD_BUS_PROPERTY("DefaultLimitNOFILE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
2471 SD_BUS_PROPERTY("DefaultLimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
2472 SD_BUS_PROPERTY("DefaultLimitAS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
2473 SD_BUS_PROPERTY("DefaultLimitASSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
2474 SD_BUS_PROPERTY("DefaultLimitNPROC", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
2475 SD_BUS_PROPERTY("DefaultLimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
2476 SD_BUS_PROPERTY("DefaultLimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
2477 SD_BUS_PROPERTY("DefaultLimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
2478 SD_BUS_PROPERTY("DefaultLimitLOCKS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
2479 SD_BUS_PROPERTY("DefaultLimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
2480 SD_BUS_PROPERTY("DefaultLimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
2481 SD_BUS_PROPERTY("DefaultLimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
2482 SD_BUS_PROPERTY("DefaultLimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
2483 SD_BUS_PROPERTY("DefaultLimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
2484 SD_BUS_PROPERTY("DefaultLimitNICE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
2485 SD_BUS_PROPERTY("DefaultLimitNICESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
2486 SD_BUS_PROPERTY("DefaultLimitRTPRIO", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
2487 SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
2488 SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
2489 SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
2490 SD_BUS_PROPERTY("DefaultTasksMax", "t", NULL, offsetof(Manager, default_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
2491 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
2492
2493 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2494 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2495 SD_BUS_METHOD("GetUnitByInvocationID", "ay", "o", method_get_unit_by_invocation_id, SD_BUS_VTABLE_UNPRIVILEGED),
2496 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2497 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2498 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
2499 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2500 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2501 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2502 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2503 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2504 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2505 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2506 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2507 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
2508 SD_BUS_METHOD("RefUnit", "s", NULL, method_ref_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2509 SD_BUS_METHOD("UnrefUnit", "s", NULL, method_unref_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2510 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2511 SD_BUS_METHOD("GetUnitProcesses", "s", "a(sus)", method_get_unit_processes, SD_BUS_VTABLE_UNPRIVILEGED),
2512 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
2513 SD_BUS_METHOD("GetJobAfter", "u", "a(usssoo)", method_get_job_waiting, SD_BUS_VTABLE_UNPRIVILEGED),
2514 SD_BUS_METHOD("GetJobBefore", "u", "a(usssoo)", method_get_job_waiting, SD_BUS_VTABLE_UNPRIVILEGED),
2515 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
2516 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2517 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
2518 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
2519 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
2520 SD_BUS_METHOD("ListUnitsByPatterns", "asas", "a(ssssssouso)", method_list_units_by_patterns, SD_BUS_VTABLE_UNPRIVILEGED),
2521 SD_BUS_METHOD("ListUnitsByNames", "as", "a(ssssssouso)", method_list_units_by_names, SD_BUS_VTABLE_UNPRIVILEGED),
2522 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2523 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2524 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2525 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
2526 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2527 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2528 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
2529 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
2530 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
2531 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2532 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2533 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2534 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2535 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2536 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2537 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2538 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2539 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2540 SD_BUS_METHOD("ListUnitFilesByPatterns", "asas", "a(ss)", method_list_unit_files_by_patterns, SD_BUS_VTABLE_UNPRIVILEGED),
2541 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
2542 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2543 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2544 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2545 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2546 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2547 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2548 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2549 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2550 SD_BUS_METHOD("RevertUnitFiles", "as", "a(sss)", method_revert_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2551 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2552 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2553 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2554 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2555 SD_BUS_METHOD("GetUnitFileLinks", "sb", "as", method_get_unit_file_links, SD_BUS_VTABLE_UNPRIVILEGED),
2556 SD_BUS_METHOD("SetExitCode", "y", NULL, method_set_exit_code, SD_BUS_VTABLE_UNPRIVILEGED),
2557 SD_BUS_METHOD("LookupDynamicUserByName", "s", "u", method_lookup_dynamic_user_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
2558 SD_BUS_METHOD("LookupDynamicUserByUID", "u", "s", method_lookup_dynamic_user_by_uid, SD_BUS_VTABLE_UNPRIVILEGED),
2559
2560 SD_BUS_SIGNAL("UnitNew", "so", 0),
2561 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2562 SD_BUS_SIGNAL("JobNew", "uos", 0),
2563 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2564 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2565 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2566 SD_BUS_SIGNAL("Reloading", "b", 0),
2567
2568 SD_BUS_VTABLE_END
2569 };
2570
2571 static int send_finished(sd_bus *bus, void *userdata) {
2572 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
2573 usec_t *times = userdata;
2574 int r;
2575
2576 assert(bus);
2577 assert(times);
2578
2579 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2580 if (r < 0)
2581 return r;
2582
2583 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2584 if (r < 0)
2585 return r;
2586
2587 return sd_bus_send(bus, message, NULL);
2588 }
2589
2590 void bus_manager_send_finished(
2591 Manager *m,
2592 usec_t firmware_usec,
2593 usec_t loader_usec,
2594 usec_t kernel_usec,
2595 usec_t initrd_usec,
2596 usec_t userspace_usec,
2597 usec_t total_usec) {
2598
2599 int r;
2600
2601 assert(m);
2602
2603 r = bus_foreach_bus(
2604 m,
2605 NULL,
2606 send_finished,
2607 (usec_t[6]) {
2608 firmware_usec,
2609 loader_usec,
2610 kernel_usec,
2611 initrd_usec,
2612 userspace_usec,
2613 total_usec
2614 });
2615 if (r < 0)
2616 log_debug_errno(r, "Failed to send finished signal: %m");
2617 }
2618
2619 static int send_reloading(sd_bus *bus, void *userdata) {
2620 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
2621 int r;
2622
2623 assert(bus);
2624
2625 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2626 if (r < 0)
2627 return r;
2628
2629 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2630 if (r < 0)
2631 return r;
2632
2633 return sd_bus_send(bus, message, NULL);
2634 }
2635
2636 void bus_manager_send_reloading(Manager *m, bool active) {
2637 int r;
2638
2639 assert(m);
2640
2641 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2642 if (r < 0)
2643 log_debug_errno(r, "Failed to send reloading signal: %m");
2644 }
2645
2646 static int send_changed_signal(sd_bus *bus, void *userdata) {
2647 assert(bus);
2648
2649 return sd_bus_emit_properties_changed_strv(bus,
2650 "/org/freedesktop/systemd1",
2651 "org.freedesktop.systemd1.Manager",
2652 NULL);
2653 }
2654
2655 void bus_manager_send_change_signal(Manager *m) {
2656 int r;
2657
2658 assert(m);
2659
2660 r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
2661 if (r < 0)
2662 log_debug_errno(r, "Failed to send manager change signal: %m");
2663 }