]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-manager.c
hashmap: introduce hash_ops to make struct Hashmap smaller
[thirdparty/systemd.git] / src / core / dbus-manager.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <unistd.h>
24
25 #include "log.h"
26 #include "strv.h"
27 #include "build.h"
28 #include "install.h"
29 #include "selinux-access.h"
30 #include "watchdog.h"
31 #include "clock-util.h"
32 #include "path-util.h"
33 #include "virt.h"
34 #include "architecture.h"
35 #include "env-util.h"
36 #include "dbus.h"
37 #include "dbus-job.h"
38 #include "dbus-manager.h"
39 #include "dbus-unit.h"
40 #include "dbus-snapshot.h"
41 #include "dbus-execute.h"
42 #include "bus-errors.h"
43
44 static int property_get_version(
45 sd_bus *bus,
46 const char *path,
47 const char *interface,
48 const char *property,
49 sd_bus_message *reply,
50 void *userdata,
51 sd_bus_error *error) {
52
53 assert(bus);
54 assert(reply);
55
56 return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
57 }
58
59 static int property_get_features(
60 sd_bus *bus,
61 const char *path,
62 const char *interface,
63 const char *property,
64 sd_bus_message *reply,
65 void *userdata,
66 sd_bus_error *error) {
67
68 assert(bus);
69 assert(reply);
70
71 return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
72 }
73
74 static int property_get_virtualization(
75 sd_bus *bus,
76 const char *path,
77 const char *interface,
78 const char *property,
79 sd_bus_message *reply,
80 void *userdata,
81 sd_bus_error *error) {
82
83 const char *id = NULL;
84
85 assert(bus);
86 assert(reply);
87
88 detect_virtualization(&id);
89
90 return sd_bus_message_append(reply, "s", id);
91 }
92
93 static int property_get_architecture(
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 assert(bus);
103 assert(reply);
104
105 return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
106 }
107
108 static int property_get_tainted(
109 sd_bus *bus,
110 const char *path,
111 const char *interface,
112 const char *property,
113 sd_bus_message *reply,
114 void *userdata,
115 sd_bus_error *error) {
116
117 char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
118 _cleanup_free_ char *p = NULL;
119 Manager *m = userdata;
120
121 assert(bus);
122 assert(reply);
123 assert(m);
124
125 if (m->taint_usr)
126 e = stpcpy(e, "split-usr:");
127
128 if (readlink_malloc("/etc/mtab", &p) < 0)
129 e = stpcpy(e, "mtab-not-symlink:");
130
131 if (access("/proc/cgroups", F_OK) < 0)
132 e = stpcpy(e, "cgroups-missing:");
133
134 if (clock_is_localtime() > 0)
135 e = stpcpy(e, "local-hwclock:");
136
137 /* remove the last ':' */
138 if (e != buf)
139 e[-1] = 0;
140
141 return sd_bus_message_append(reply, "s", buf);
142 }
143
144 static int property_get_log_target(
145 sd_bus *bus,
146 const char *path,
147 const char *interface,
148 const char *property,
149 sd_bus_message *reply,
150 void *userdata,
151 sd_bus_error *error) {
152
153 assert(bus);
154 assert(reply);
155
156 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
157 }
158
159 static int property_set_log_target(
160 sd_bus *bus,
161 const char *path,
162 const char *interface,
163 const char *property,
164 sd_bus_message *value,
165 void *userdata,
166 sd_bus_error *error) {
167
168 const char *t;
169 int r;
170
171 assert(bus);
172 assert(value);
173
174 r = sd_bus_message_read(value, "s", &t);
175 if (r < 0)
176 return r;
177
178 return log_set_target_from_string(t);
179 }
180
181 static int property_get_log_level(
182 sd_bus *bus,
183 const char *path,
184 const char *interface,
185 const char *property,
186 sd_bus_message *reply,
187 void *userdata,
188 sd_bus_error *error) {
189
190 _cleanup_free_ char *t = NULL;
191 int r;
192
193 assert(bus);
194 assert(reply);
195
196 r = log_level_to_string_alloc(log_get_max_level(), &t);
197 if (r < 0)
198 return r;
199
200 return sd_bus_message_append(reply, "s", t);
201 }
202
203 static int property_set_log_level(
204 sd_bus *bus,
205 const char *path,
206 const char *interface,
207 const char *property,
208 sd_bus_message *value,
209 void *userdata,
210 sd_bus_error *error) {
211
212 const char *t;
213 int r;
214
215 assert(bus);
216 assert(value);
217
218 r = sd_bus_message_read(value, "s", &t);
219 if (r < 0)
220 return r;
221
222 return log_set_max_level_from_string(t);
223 }
224
225 static int property_get_n_names(
226 sd_bus *bus,
227 const char *path,
228 const char *interface,
229 const char *property,
230 sd_bus_message *reply,
231 void *userdata,
232 sd_bus_error *error) {
233
234 Manager *m = userdata;
235
236 assert(bus);
237 assert(reply);
238 assert(m);
239
240 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
241 }
242
243 static int property_get_n_failed_units(
244 sd_bus *bus,
245 const char *path,
246 const char *interface,
247 const char *property,
248 sd_bus_message *reply,
249 void *userdata,
250 sd_bus_error *error) {
251
252 Manager *m = userdata;
253
254 assert(bus);
255 assert(reply);
256 assert(m);
257
258 return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
259 }
260
261 static int property_get_n_jobs(
262 sd_bus *bus,
263 const char *path,
264 const char *interface,
265 const char *property,
266 sd_bus_message *reply,
267 void *userdata,
268 sd_bus_error *error) {
269
270 Manager *m = userdata;
271
272 assert(bus);
273 assert(reply);
274 assert(m);
275
276 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
277 }
278
279 static int property_get_progress(
280 sd_bus *bus,
281 const char *path,
282 const char *interface,
283 const char *property,
284 sd_bus_message *reply,
285 void *userdata,
286 sd_bus_error *error) {
287
288 Manager *m = userdata;
289 double d;
290
291 assert(bus);
292 assert(reply);
293 assert(m);
294
295 if (dual_timestamp_is_set(&m->finish_timestamp))
296 d = 1.0;
297 else
298 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
299
300 return sd_bus_message_append(reply, "d", d);
301 }
302
303 static int property_get_system_state(
304 sd_bus *bus,
305 const char *path,
306 const char *interface,
307 const char *property,
308 sd_bus_message *reply,
309 void *userdata,
310 sd_bus_error *error) {
311
312 Manager *m = userdata;
313
314 assert(bus);
315 assert(reply);
316 assert(m);
317
318 return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
319 }
320
321 static int property_set_runtime_watchdog(
322 sd_bus *bus,
323 const char *path,
324 const char *interface,
325 const char *property,
326 sd_bus_message *value,
327 void *userdata,
328 sd_bus_error *error) {
329
330 usec_t *t = userdata;
331 int r;
332
333 assert(bus);
334 assert(value);
335
336 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
337
338 r = sd_bus_message_read(value, "t", t);
339 if (r < 0)
340 return r;
341
342 return watchdog_set_timeout(t);
343 }
344
345 static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
346 _cleanup_free_ char *path = NULL;
347 Manager *m = userdata;
348 const char *name;
349 Unit *u;
350 int r;
351
352 assert(bus);
353 assert(message);
354 assert(m);
355
356 /* Anyone can call this method */
357
358 r = sd_bus_message_read(message, "s", &name);
359 if (r < 0)
360 return r;
361
362 u = manager_get_unit(m, name);
363 if (!u)
364 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
365
366 r = selinux_unit_access_check(u, message, "status", error);
367 if (r < 0)
368 return r;
369
370 path = unit_dbus_path(u);
371 if (!path)
372 return -ENOMEM;
373
374 return sd_bus_reply_method_return(message, "o", path);
375 }
376
377 static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
378 _cleanup_free_ char *path = NULL;
379 Manager *m = userdata;
380 pid_t pid;
381 Unit *u;
382 int r;
383
384 assert(bus);
385 assert(message);
386 assert(m);
387
388 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
389
390 /* Anyone can call this method */
391
392 r = sd_bus_message_read(message, "u", &pid);
393 if (r < 0)
394 return r;
395
396 if (pid == 0) {
397 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
398
399 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
400 if (r < 0)
401 return r;
402
403 r = sd_bus_creds_get_pid(creds, &pid);
404 if (r < 0)
405 return r;
406 }
407
408 u = manager_get_unit_by_pid(m, pid);
409 if (!u)
410 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
411
412 r = selinux_unit_access_check(u, message, "status", error);
413 if (r < 0)
414 return r;
415
416 path = unit_dbus_path(u);
417 if (!path)
418 return -ENOMEM;
419
420 return sd_bus_reply_method_return(message, "o", path);
421 }
422
423 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
424 _cleanup_free_ char *path = NULL;
425 Manager *m = userdata;
426 const char *name;
427 Unit *u;
428 int r;
429
430 assert(bus);
431 assert(message);
432 assert(m);
433
434 /* Anyone can call this method */
435
436 r = sd_bus_message_read(message, "s", &name);
437 if (r < 0)
438 return r;
439
440 r = manager_load_unit(m, name, NULL, error, &u);
441 if (r < 0)
442 return r;
443
444 r = selinux_unit_access_check(u, message, "status", error);
445 if (r < 0)
446 return r;
447
448 path = unit_dbus_path(u);
449 if (!path)
450 return -ENOMEM;
451
452 return sd_bus_reply_method_return(message, "o", path);
453 }
454
455 static int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
456 const char *name;
457 Unit *u;
458 int r;
459
460 assert(bus);
461 assert(message);
462 assert(m);
463
464 r = bus_verify_manage_unit_async(m, message, error);
465 if (r < 0)
466 return r;
467 if (r == 0)
468 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
469
470 r = sd_bus_message_read(message, "s", &name);
471 if (r < 0)
472 return r;
473
474 r = manager_load_unit(m, name, NULL, error, &u);
475 if (r < 0)
476 return r;
477
478 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
479 }
480
481 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
482 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
483 }
484
485 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
486 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
487 }
488
489 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
490 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
491 }
492
493 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
494 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
495 }
496
497 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
498 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
499 }
500
501 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
502 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
503 }
504
505 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
506 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
507 }
508
509 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
510 Manager *m = userdata;
511 const char *old_name;
512 Unit *u;
513 int r;
514
515 assert(bus);
516 assert(message);
517 assert(m);
518
519 r = bus_verify_manage_unit_async(m, message, error);
520 if (r < 0)
521 return r;
522 if (r == 0)
523 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
524
525 r = sd_bus_message_read(message, "s", &old_name);
526 if (r < 0)
527 return r;
528
529 u = manager_get_unit(m, old_name);
530 if (!u || !u->job || u->job->type != JOB_START)
531 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
532
533 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
534 }
535
536 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
537 Manager *m = userdata;
538 const char *name;
539 Unit *u;
540 int r;
541
542 assert(bus);
543 assert(message);
544 assert(m);
545
546 /* Like bus_verify_manage_unit_async(), but uses CAP_SYS_KILL */
547 r = bus_verify_manage_unit_async_for_kill(m, message, error);
548 if (r < 0)
549 return r;
550 if (r == 0)
551 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
552
553 r = sd_bus_message_read(message, "s", &name);
554 if (r < 0)
555 return r;
556
557 u = manager_get_unit(m, name);
558 if (!u)
559 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
560
561 return bus_unit_method_kill(bus, message, u, error);
562 }
563
564 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
565 Manager *m = userdata;
566 const char *name;
567 Unit *u;
568 int r;
569
570 assert(bus);
571 assert(message);
572 assert(m);
573
574 r = bus_verify_manage_unit_async(m, message, error);
575 if (r < 0)
576 return r;
577 if (r == 0)
578 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
579
580 r = sd_bus_message_read(message, "s", &name);
581 if (r < 0)
582 return r;
583
584 u = manager_get_unit(m, name);
585 if (!u)
586 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
587
588 return bus_unit_method_reset_failed(bus, message, u, error);
589 }
590
591 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
592 Manager *m = userdata;
593 const char *name;
594 Unit *u;
595 int r;
596
597 assert(bus);
598 assert(message);
599 assert(m);
600
601 r = bus_verify_manage_unit_async(m, message, error);
602 if (r < 0)
603 return r;
604 if (r == 0)
605 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
606
607 r = sd_bus_message_read(message, "s", &name);
608 if (r < 0)
609 return r;
610
611 u = manager_get_unit(m, name);
612 if (!u)
613 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
614
615 return bus_unit_method_set_properties(bus, message, u, error);
616 }
617
618 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
619 const char *name, *smode;
620 Manager *m = userdata;
621 JobMode mode;
622 UnitType t;
623 Unit *u;
624 int r;
625
626 assert(bus);
627 assert(message);
628 assert(m);
629
630 r = bus_verify_manage_unit_async(m, message, error);
631 if (r < 0)
632 return r;
633 if (r == 0)
634 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
635
636 r = sd_bus_message_read(message, "ss", &name, &smode);
637 if (r < 0)
638 return r;
639
640 t = unit_name_to_type(name);
641 if (t < 0)
642 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
643
644 if (!unit_vtable[t]->can_transient)
645 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
646
647 mode = job_mode_from_string(smode);
648 if (mode < 0)
649 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
650
651 r = selinux_access_check(message, "start", error);
652 if (r < 0)
653 return r;
654
655 r = manager_load_unit(m, name, NULL, error, &u);
656 if (r < 0)
657 return r;
658
659 if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
660 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
661
662 /* OK, the unit failed to load and is unreferenced, now let's
663 * fill in the transient data instead */
664 r = unit_make_transient(u);
665 if (r < 0)
666 return r;
667
668 /* Set our properties */
669 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
670 if (r < 0)
671 return r;
672
673 /* And load this stub fully */
674 r = unit_load(u);
675 if (r < 0)
676 return r;
677
678 manager_dispatch_load_queue(m);
679
680 /* Finally, start it */
681 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
682 }
683
684 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
685 _cleanup_free_ char *path = NULL;
686 Manager *m = userdata;
687 uint32_t id;
688 Job *j;
689 int r;
690
691 assert(bus);
692 assert(message);
693 assert(m);
694
695 /* Anyone can call this method */
696
697 r = sd_bus_message_read(message, "u", &id);
698 if (r < 0)
699 return r;
700
701 j = manager_get_job(m, id);
702 if (!j)
703 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
704
705 r = selinux_unit_access_check(j->unit, message, "status", error);
706 if (r < 0)
707 return r;
708
709 path = job_dbus_path(j);
710 if (!path)
711 return -ENOMEM;
712
713 return sd_bus_reply_method_return(message, "o", path);
714 }
715
716 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
717 Manager *m = userdata;
718 uint32_t id;
719 Job *j;
720 int r;
721
722 assert(bus);
723 assert(message);
724 assert(m);
725
726 r = sd_bus_message_read(message, "u", &id);
727 if (r < 0)
728 return r;
729
730 j = manager_get_job(m, id);
731 if (!j)
732 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
733
734 return bus_job_method_cancel(bus, message, j, error);
735 }
736
737 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
738 Manager *m = userdata;
739 int r;
740
741 assert(bus);
742 assert(message);
743 assert(m);
744
745 r = selinux_access_check(message, "reboot", error);
746 if (r < 0)
747 return r;
748
749 manager_clear_jobs(m);
750
751 return sd_bus_reply_method_return(message, NULL);
752 }
753
754 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
755 Manager *m = userdata;
756 int r;
757
758 assert(bus);
759 assert(message);
760 assert(m);
761
762 r = selinux_access_check(message, "reload", error);
763 if (r < 0)
764 return r;
765
766 manager_reset_failed(m);
767
768 return sd_bus_reply_method_return(message, NULL);
769 }
770
771 static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
772 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
773 Manager *m = userdata;
774 const char *k;
775 Iterator i;
776 Unit *u;
777 int r;
778
779 assert(bus);
780 assert(message);
781 assert(m);
782
783 /* Anyone can call this method */
784
785 r = selinux_access_check(message, "status", error);
786 if (r < 0)
787 return r;
788
789 r = sd_bus_message_new_method_return(message, &reply);
790 if (r < 0)
791 return r;
792
793 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
794 if (r < 0)
795 return r;
796
797 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
798 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
799 Unit *following;
800
801 if (k != u->id)
802 continue;
803
804 following = unit_following(u);
805
806 if (!strv_isempty(states) &&
807 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
808 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
809 !strv_contains(states, unit_sub_state_to_string(u)))
810 continue;
811
812 unit_path = unit_dbus_path(u);
813 if (!unit_path)
814 return -ENOMEM;
815
816 if (u->job) {
817 job_path = job_dbus_path(u->job);
818 if (!job_path)
819 return -ENOMEM;
820 }
821
822 r = sd_bus_message_append(
823 reply, "(ssssssouso)",
824 u->id,
825 unit_description(u),
826 unit_load_state_to_string(u->load_state),
827 unit_active_state_to_string(unit_active_state(u)),
828 unit_sub_state_to_string(u),
829 following ? following->id : "",
830 unit_path,
831 u->job ? u->job->id : 0,
832 u->job ? job_type_to_string(u->job->type) : "",
833 job_path ? job_path : "/");
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(bus, reply, NULL);
843 }
844
845 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
846 return list_units_filtered(bus, message, userdata, error, NULL);
847 }
848
849 static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
850 _cleanup_strv_free_ char **states = NULL;
851 int r;
852
853 r = sd_bus_message_read_strv(message, &states);
854 if (r < 0)
855 return r;
856
857 return list_units_filtered(bus, message, userdata, error, states);
858 }
859
860 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
861 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
862 Manager *m = userdata;
863 Iterator i;
864 Job *j;
865 int r;
866
867 assert(bus);
868 assert(message);
869 assert(m);
870
871 /* Anyone can call this method */
872
873 r = selinux_access_check(message, "status", error);
874 if (r < 0)
875 return r;
876
877 r = sd_bus_message_new_method_return(message, &reply);
878 if (r < 0)
879 return r;
880
881 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
882 if (r < 0)
883 return r;
884
885 HASHMAP_FOREACH(j, m->jobs, i) {
886 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
887
888 job_path = job_dbus_path(j);
889 if (!job_path)
890 return -ENOMEM;
891
892 unit_path = unit_dbus_path(j->unit);
893 if (!unit_path)
894 return -ENOMEM;
895
896 r = sd_bus_message_append(
897 reply, "(usssoo)",
898 j->id,
899 j->unit->id,
900 job_type_to_string(j->type),
901 job_state_to_string(j->state),
902 job_path,
903 unit_path);
904 if (r < 0)
905 return r;
906 }
907
908 r = sd_bus_message_close_container(reply);
909 if (r < 0)
910 return r;
911
912 return sd_bus_send(bus, reply, NULL);
913 }
914
915 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
916 Manager *m = userdata;
917 int r;
918
919 assert(bus);
920 assert(message);
921 assert(m);
922
923 /* Anyone can call this method */
924
925 r = selinux_access_check(message, "status", error);
926 if (r < 0)
927 return r;
928
929 if (bus == m->api_bus) {
930
931 /* Note that direct bus connection subscribe by
932 * default, we only track peers on the API bus here */
933
934 if (!m->subscribed) {
935 r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
936 if (r < 0)
937 return r;
938 }
939
940 r = sd_bus_track_add_sender(m->subscribed, message);
941 if (r < 0)
942 return r;
943 if (r == 0)
944 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
945 }
946
947 return sd_bus_reply_method_return(message, NULL);
948 }
949
950 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
951 Manager *m = userdata;
952 int r;
953
954 assert(bus);
955 assert(message);
956 assert(m);
957
958 /* Anyone can call this method */
959
960 r = selinux_access_check(message, "status", error);
961 if (r < 0)
962 return r;
963
964 if (bus == m->api_bus) {
965 r = sd_bus_track_remove_sender(m->subscribed, message);
966 if (r < 0)
967 return r;
968 if (r == 0)
969 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
970 }
971
972 return sd_bus_reply_method_return(message, NULL);
973 }
974
975 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
976 _cleanup_free_ char *dump = NULL;
977 _cleanup_fclose_ FILE *f = NULL;
978 Manager *m = userdata;
979 size_t size;
980 int r;
981
982 assert(bus);
983 assert(message);
984 assert(m);
985
986 /* Anyone can call this method */
987
988 r = selinux_access_check(message, "status", error);
989 if (r < 0)
990 return r;
991
992 f = open_memstream(&dump, &size);
993 if (!f)
994 return -ENOMEM;
995
996 manager_dump_units(m, f, NULL);
997 manager_dump_jobs(m, f, NULL);
998
999 fflush(f);
1000
1001 if (ferror(f))
1002 return -ENOMEM;
1003
1004 return sd_bus_reply_method_return(message, "s", dump);
1005 }
1006
1007 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1008 _cleanup_free_ char *path = NULL;
1009 Manager *m = userdata;
1010 const char *name;
1011 int cleanup;
1012 Snapshot *s = NULL;
1013 int r;
1014
1015 assert(bus);
1016 assert(message);
1017 assert(m);
1018
1019 r = selinux_access_check(message, "start", error);
1020 if (r < 0)
1021 return r;
1022
1023 r = sd_bus_message_read(message, "sb", &name, &cleanup);
1024 if (r < 0)
1025 return r;
1026
1027 if (isempty(name))
1028 name = NULL;
1029
1030 r = snapshot_create(m, name, cleanup, error, &s);
1031 if (r < 0)
1032 return r;
1033
1034 path = unit_dbus_path(UNIT(s));
1035 if (!path)
1036 return -ENOMEM;
1037
1038 return sd_bus_reply_method_return(message, "o", path);
1039 }
1040
1041 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1042 Manager *m = userdata;
1043 const char *name;
1044 Unit *u;
1045 int r;
1046
1047 assert(bus);
1048 assert(message);
1049 assert(m);
1050
1051 r = selinux_access_check(message, "stop", error);
1052 if (r < 0)
1053 return r;
1054
1055 r = sd_bus_message_read(message, "s", &name);
1056 if (r < 0)
1057 return r;
1058
1059 u = manager_get_unit(m, name);
1060 if (!u)
1061 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
1062
1063 if (u->type != UNIT_SNAPSHOT)
1064 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
1065
1066 return bus_snapshot_method_remove(bus, message, u, error);
1067 }
1068
1069 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1070 Manager *m = userdata;
1071 int r;
1072
1073 assert(bus);
1074 assert(message);
1075 assert(m);
1076
1077 r = bus_verify_reload_daemon_async(m, message, error);
1078 if (r < 0)
1079 return r;
1080 if (r == 0)
1081 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1082
1083 r = selinux_access_check(message, "reload", error);
1084 if (r < 0)
1085 return r;
1086
1087 /* Instead of sending the reply back right away, we just
1088 * remember that we need to and then send it after the reload
1089 * is finished. That way the caller knows when the reload
1090 * finished. */
1091
1092 assert(!m->queued_message);
1093 r = sd_bus_message_new_method_return(message, &m->queued_message);
1094 if (r < 0)
1095 return r;
1096
1097 m->queued_message_bus = sd_bus_ref(bus);
1098 m->exit_code = MANAGER_RELOAD;
1099
1100 return 1;
1101 }
1102
1103 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1104 Manager *m = userdata;
1105 int r;
1106
1107 assert(bus);
1108 assert(message);
1109 assert(m);
1110
1111 r = bus_verify_reload_daemon_async(m, message, error);
1112 if (r < 0)
1113 return r;
1114 if (r == 0)
1115 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1116
1117 r = selinux_access_check(message, "reload", error);
1118 if (r < 0)
1119 return r;
1120
1121 /* We don't send a reply back here, the client should
1122 * just wait for us disconnecting. */
1123
1124 m->exit_code = MANAGER_REEXECUTE;
1125 return 1;
1126 }
1127
1128 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1129 Manager *m = userdata;
1130 int r;
1131
1132 assert(bus);
1133 assert(message);
1134 assert(m);
1135
1136 r = selinux_access_check(message, "halt", error);
1137 if (r < 0)
1138 return r;
1139
1140 if (m->running_as == SYSTEMD_SYSTEM)
1141 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1142
1143 m->exit_code = MANAGER_EXIT;
1144
1145 return sd_bus_reply_method_return(message, NULL);
1146 }
1147
1148 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1149 Manager *m = userdata;
1150 int r;
1151
1152 assert(bus);
1153 assert(message);
1154 assert(m);
1155
1156 r = selinux_access_check(message, "reboot", error);
1157 if (r < 0)
1158 return r;
1159
1160 if (m->running_as != SYSTEMD_SYSTEM)
1161 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1162
1163 m->exit_code = MANAGER_REBOOT;
1164
1165 return sd_bus_reply_method_return(message, NULL);
1166 }
1167
1168
1169 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1170 Manager *m = userdata;
1171 int r;
1172
1173 assert(bus);
1174 assert(message);
1175 assert(m);
1176
1177 r = selinux_access_check(message, "halt", error);
1178 if (r < 0)
1179 return r;
1180
1181 if (m->running_as != SYSTEMD_SYSTEM)
1182 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1183
1184 m->exit_code = MANAGER_POWEROFF;
1185
1186 return sd_bus_reply_method_return(message, NULL);
1187 }
1188
1189 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1190 Manager *m = userdata;
1191 int r;
1192
1193 assert(bus);
1194 assert(message);
1195 assert(m);
1196
1197 r = selinux_access_check(message, "halt", error);
1198 if (r < 0)
1199 return r;
1200
1201 if (m->running_as != SYSTEMD_SYSTEM)
1202 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1203
1204 m->exit_code = MANAGER_HALT;
1205
1206 return sd_bus_reply_method_return(message, NULL);
1207 }
1208
1209 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1210 Manager *m = userdata;
1211 int r;
1212
1213 assert(bus);
1214 assert(message);
1215 assert(m);
1216
1217 r = selinux_access_check(message, "reboot", error);
1218 if (r < 0)
1219 return r;
1220
1221 if (m->running_as != SYSTEMD_SYSTEM)
1222 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1223
1224 m->exit_code = MANAGER_KEXEC;
1225
1226 return sd_bus_reply_method_return(message, NULL);
1227 }
1228
1229 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1230 char *ri = NULL, *rt = NULL;
1231 const char *root, *init;
1232 Manager *m = userdata;
1233 int r;
1234
1235 assert(bus);
1236 assert(message);
1237 assert(m);
1238
1239 r = selinux_access_check(message, "reboot", error);
1240 if (r < 0)
1241 return r;
1242
1243 if (m->running_as != SYSTEMD_SYSTEM)
1244 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1245
1246 r = sd_bus_message_read(message, "ss", &root, &init);
1247 if (r < 0)
1248 return r;
1249
1250 if (path_equal(root, "/") || !path_is_absolute(root))
1251 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1252
1253 /* Safety check */
1254 if (isempty(init)) {
1255 if (!path_is_os_tree(root))
1256 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);
1257 } else {
1258 _cleanup_free_ char *p = NULL;
1259
1260 if (!path_is_absolute(init))
1261 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1262
1263 p = strappend(root, init);
1264 if (!p)
1265 return -ENOMEM;
1266
1267 if (access(p, X_OK) < 0)
1268 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1269 }
1270
1271 rt = strdup(root);
1272 if (!rt)
1273 return -ENOMEM;
1274
1275 if (!isempty(init)) {
1276 ri = strdup(init);
1277 if (!ri) {
1278 free(rt);
1279 return -ENOMEM;
1280 }
1281 }
1282
1283 free(m->switch_root);
1284 m->switch_root = rt;
1285
1286 free(m->switch_root_init);
1287 m->switch_root_init = ri;
1288
1289 m->exit_code = MANAGER_SWITCH_ROOT;
1290
1291 return sd_bus_reply_method_return(message, NULL);
1292 }
1293
1294 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1295 _cleanup_strv_free_ char **plus = NULL;
1296 Manager *m = userdata;
1297 int r;
1298
1299 assert(bus);
1300 assert(message);
1301 assert(m);
1302
1303 r = selinux_access_check(message, "reload", error);
1304 if (r < 0)
1305 return r;
1306
1307 r = sd_bus_message_read_strv(message, &plus);
1308 if (r < 0)
1309 return r;
1310 if (!strv_env_is_valid(plus))
1311 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1312
1313 r = manager_environment_add(m, NULL, plus);
1314 if (r < 0)
1315 return r;
1316
1317 return sd_bus_reply_method_return(message, NULL);
1318 }
1319
1320 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1321 _cleanup_strv_free_ char **minus = NULL;
1322 Manager *m = userdata;
1323 int r;
1324
1325 assert(bus);
1326 assert(message);
1327 assert(m);
1328
1329 r = selinux_access_check(message, "reload", error);
1330 if (r < 0)
1331 return r;
1332
1333 r = sd_bus_message_read_strv(message, &minus);
1334 if (r < 0)
1335 return r;
1336
1337 if (!strv_env_name_or_assignment_is_valid(minus))
1338 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1339
1340 r = manager_environment_add(m, minus, NULL);
1341 if (r < 0)
1342 return r;
1343
1344 return sd_bus_reply_method_return(message, NULL);
1345 }
1346
1347 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1348 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1349 Manager *m = userdata;
1350 int r;
1351
1352 assert(bus);
1353 assert(message);
1354 assert(m);
1355
1356 r = selinux_access_check(message, "reload", error);
1357 if (r < 0)
1358 return r;
1359
1360 r = sd_bus_message_read_strv(message, &minus);
1361 if (r < 0)
1362 return r;
1363
1364 r = sd_bus_message_read_strv(message, &plus);
1365 if (r < 0)
1366 return r;
1367
1368 if (!strv_env_name_or_assignment_is_valid(minus))
1369 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1370 if (!strv_env_is_valid(plus))
1371 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1372
1373 r = manager_environment_add(m, minus, plus);
1374 if (r < 0)
1375 return r;
1376
1377 return sd_bus_reply_method_return(message, NULL);
1378 }
1379
1380 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1381 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1382 Manager *m = userdata;
1383 UnitFileList *item;
1384 Hashmap *h;
1385 Iterator i;
1386 int r;
1387
1388 assert(bus);
1389 assert(message);
1390 assert(m);
1391
1392 /* Anyone can call this method */
1393
1394 r = selinux_access_check(message, "status", error);
1395 if (r < 0)
1396 return r;
1397
1398 r = sd_bus_message_new_method_return(message, &reply);
1399 if (r < 0)
1400 return r;
1401
1402 h = hashmap_new(&string_hash_ops);
1403 if (!h)
1404 return -ENOMEM;
1405
1406 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1407 if (r < 0)
1408 goto fail;
1409
1410 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1411 if (r < 0)
1412 goto fail;
1413
1414 HASHMAP_FOREACH(item, h, i) {
1415
1416 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1417 if (r < 0)
1418 goto fail;
1419 }
1420
1421 unit_file_list_free(h);
1422
1423 r = sd_bus_message_close_container(reply);
1424 if (r < 0)
1425 return r;
1426
1427 return sd_bus_send(bus, reply, NULL);
1428
1429 fail:
1430 unit_file_list_free(h);
1431 return r;
1432 }
1433
1434 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1435 Manager *m = userdata;
1436 const char *name;
1437 UnitFileState state;
1438 UnitFileScope scope;
1439 int r;
1440
1441 assert(bus);
1442 assert(message);
1443 assert(m);
1444
1445 /* Anyone can call this method */
1446
1447 r = selinux_access_check(message, "status", error);
1448 if (r < 0)
1449 return r;
1450
1451 r = sd_bus_message_read(message, "s", &name);
1452 if (r < 0)
1453 return r;
1454
1455 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1456
1457 state = unit_file_get_state(scope, NULL, name);
1458 if (state < 0)
1459 return state;
1460
1461 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1462 }
1463
1464 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1465 _cleanup_free_ char *default_target = NULL;
1466 Manager *m = userdata;
1467 UnitFileScope scope;
1468 int r;
1469
1470 assert(bus);
1471 assert(message);
1472 assert(m);
1473
1474 /* Anyone can call this method */
1475
1476 r = selinux_access_check(message, "status", error);
1477 if (r < 0)
1478 return r;
1479
1480 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1481
1482 r = unit_file_get_default(scope, NULL, &default_target);
1483 if (r < 0)
1484 return r;
1485
1486 return sd_bus_reply_method_return(message, "s", default_target);
1487 }
1488
1489 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1490 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1491 int r;
1492
1493 assert(bus);
1494
1495 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1496 if (r < 0)
1497 return r;
1498
1499 return sd_bus_send(bus, message, NULL);
1500 }
1501
1502 static int reply_unit_file_changes_and_free(
1503 Manager *m,
1504 sd_bus *bus,
1505 sd_bus_message *message,
1506 int carries_install_info,
1507 UnitFileChange *changes,
1508 unsigned n_changes) {
1509
1510 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1511 unsigned i;
1512 int r;
1513
1514 if (n_changes > 0) {
1515 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1516 if (r < 0)
1517 log_debug("Failed to send UnitFilesChanged signal: %s", strerror(-r));
1518 }
1519
1520 r = sd_bus_message_new_method_return(message, &reply);
1521 if (r < 0)
1522 goto fail;
1523
1524 if (carries_install_info >= 0) {
1525 r = sd_bus_message_append(reply, "b", carries_install_info);
1526 if (r < 0)
1527 goto fail;
1528 }
1529
1530 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1531 if (r < 0)
1532 goto fail;
1533
1534 for (i = 0; i < n_changes; i++) {
1535 r = sd_bus_message_append(
1536 reply, "(sss)",
1537 unit_file_change_type_to_string(changes[i].type),
1538 changes[i].path,
1539 changes[i].source);
1540 if (r < 0)
1541 goto fail;
1542 }
1543
1544 r = sd_bus_message_close_container(reply);
1545 if (r < 0)
1546 goto fail;
1547
1548 return sd_bus_send(bus, reply, NULL);
1549
1550 fail:
1551 unit_file_changes_free(changes, n_changes);
1552 return r;
1553 }
1554
1555 static int method_enable_unit_files_generic(
1556 sd_bus *bus,
1557 sd_bus_message *message,
1558 Manager *m,
1559 const char *verb,
1560 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1561 bool carries_install_info,
1562 sd_bus_error *error) {
1563
1564 _cleanup_strv_free_ char **l = NULL;
1565 #ifdef HAVE_SELINUX
1566 char **i;
1567 #endif
1568 UnitFileChange *changes = NULL;
1569 unsigned n_changes = 0;
1570 UnitFileScope scope;
1571 int runtime, force, r;
1572
1573 assert(bus);
1574 assert(message);
1575 assert(m);
1576
1577 r = bus_verify_manage_unit_files_async(m, message, error);
1578 if (r < 0)
1579 return r;
1580 if (r == 0)
1581 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1582
1583 r = sd_bus_message_read_strv(message, &l);
1584 if (r < 0)
1585 return r;
1586
1587 r = sd_bus_message_read(message, "bb", &runtime, &force);
1588 if (r < 0)
1589 return r;
1590
1591 #ifdef HAVE_SELINUX
1592 STRV_FOREACH(i, l) {
1593 Unit *u;
1594
1595 u = manager_get_unit(m, *i);
1596 if (u) {
1597 r = selinux_unit_access_check(u, message, verb, error);
1598 if (r < 0)
1599 return r;
1600 }
1601 }
1602 #endif
1603
1604 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1605
1606 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1607 if (r < 0)
1608 return r;
1609
1610 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1611 }
1612
1613 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1614 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1615 }
1616
1617 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1618 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1619 }
1620
1621 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1622 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1623 }
1624
1625 static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1626 return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1627 }
1628
1629 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1630 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
1631 }
1632
1633 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1634 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1635 }
1636
1637 static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1638
1639 _cleanup_strv_free_ char **l = NULL;
1640 #ifdef HAVE_SELINUX
1641 char **i;
1642 #endif
1643 UnitFileChange *changes = NULL;
1644 unsigned n_changes = 0;
1645 Manager *m = userdata;
1646 UnitFilePresetMode mm;
1647 UnitFileScope scope;
1648 int runtime, force, r;
1649 const char *mode;
1650
1651 assert(bus);
1652 assert(message);
1653 assert(m);
1654
1655 r = bus_verify_manage_unit_files_async(m, message, error);
1656 if (r < 0)
1657 return r;
1658 if (r == 0)
1659 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1660
1661 r = sd_bus_message_read_strv(message, &l);
1662 if (r < 0)
1663 return r;
1664
1665 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1666 if (r < 0)
1667 return r;
1668
1669 if (isempty(mode))
1670 mm = UNIT_FILE_PRESET_FULL;
1671 else {
1672 mm = unit_file_preset_mode_from_string(mode);
1673 if (mm < 0)
1674 return -EINVAL;
1675 }
1676
1677 #ifdef HAVE_SELINUX
1678 STRV_FOREACH(i, l) {
1679 Unit *u;
1680
1681 u = manager_get_unit(m, *i);
1682 if (u) {
1683 r = selinux_unit_access_check(u, message, "enable", error);
1684 if (r < 0)
1685 return r;
1686 }
1687 }
1688 #endif
1689
1690 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1691
1692 r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
1693 if (r < 0)
1694 return r;
1695
1696 return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
1697 }
1698
1699 static int method_disable_unit_files_generic(
1700 sd_bus *bus,
1701 sd_bus_message *message,
1702 Manager *m, const
1703 char *verb,
1704 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1705 sd_bus_error *error) {
1706
1707 _cleanup_strv_free_ char **l = NULL;
1708 UnitFileChange *changes = NULL;
1709 unsigned n_changes = 0;
1710 UnitFileScope scope;
1711 int r, runtime;
1712
1713 assert(bus);
1714 assert(message);
1715 assert(m);
1716
1717 r = bus_verify_manage_unit_files_async(m, message, error);
1718 if (r < 0)
1719 return r;
1720 if (r == 0)
1721 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1722
1723 r = selinux_access_check(message, verb, error);
1724 if (r < 0)
1725 return r;
1726
1727 r = sd_bus_message_read_strv(message, &l);
1728 if (r < 0)
1729 return r;
1730
1731 r = sd_bus_message_read(message, "b", &runtime);
1732 if (r < 0)
1733 return r;
1734
1735 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1736
1737 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1738 if (r < 0)
1739 return r;
1740
1741 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1742 }
1743
1744 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1745 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1746 }
1747
1748 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1749 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1750 }
1751
1752 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1753 UnitFileChange *changes = NULL;
1754 unsigned n_changes = 0;
1755 Manager *m = userdata;
1756 UnitFileScope scope;
1757 const char *name;
1758 int force, r;
1759
1760 assert(bus);
1761 assert(message);
1762 assert(m);
1763
1764 r = bus_verify_manage_unit_files_async(m, message, error);
1765 if (r < 0)
1766 return r;
1767 if (r == 0)
1768 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1769
1770 r = selinux_access_check(message, "enable", error);
1771 if (r < 0)
1772 return r;
1773
1774 r = sd_bus_message_read(message, "sb", &name, &force);
1775 if (r < 0)
1776 return r;
1777
1778 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1779
1780 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1781 if (r < 0)
1782 return r;
1783
1784 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1785 }
1786
1787 static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1788 UnitFileChange *changes = NULL;
1789 unsigned n_changes = 0;
1790 Manager *m = userdata;
1791 UnitFilePresetMode mm;
1792 UnitFileScope scope;
1793 const char *mode;
1794 int force, runtime, r;
1795
1796 assert(bus);
1797 assert(message);
1798 assert(m);
1799
1800 r = bus_verify_manage_unit_files_async(m, message, error);
1801 if (r < 0)
1802 return r;
1803 if (r == 0)
1804 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1805
1806 r = selinux_access_check(message, "enable", error);
1807 if (r < 0)
1808 return r;
1809
1810 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1811 if (r < 0)
1812 return r;
1813
1814 if (isempty(mode))
1815 mm = UNIT_FILE_PRESET_FULL;
1816 else {
1817 mm = unit_file_preset_mode_from_string(mode);
1818 if (mm < 0)
1819 return -EINVAL;
1820 }
1821
1822 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1823
1824 r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
1825 if (r < 0)
1826 return r;
1827
1828 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1829 }
1830
1831 const sd_bus_vtable bus_manager_vtable[] = {
1832 SD_BUS_VTABLE_START(0),
1833
1834 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1835 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1836 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1837 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1838 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1839 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1840 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1841 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1842 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1843 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1844 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1845 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1846 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1847 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1848 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1849 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1850 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1851 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1852 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1853 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1854 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, 0),
1855 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1856 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1857 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1858 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1859 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1860 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1861 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1862 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1863 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1864 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1865 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1866 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1867 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1868 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
1869
1870 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1871 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1872 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1873 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1874 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
1875 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1876 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1877 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1878 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1879 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1880 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1881 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1882 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1883 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
1884 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1885 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1886 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
1887 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1888 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1889 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1890 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
1891 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1892 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1893 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1894 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1895 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1896 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1897 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
1898 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
1899 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1900 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1901 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1902 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1903 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1904 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1905 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
1906 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
1907 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
1908 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1909 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
1910 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1911 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1912 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1913 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1914 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1915 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
1916 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1917 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1918 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
1919 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
1920 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1921
1922 SD_BUS_SIGNAL("UnitNew", "so", 0),
1923 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1924 SD_BUS_SIGNAL("JobNew", "uos", 0),
1925 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1926 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1927 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
1928 SD_BUS_SIGNAL("Reloading", "b", 0),
1929
1930 SD_BUS_VTABLE_END
1931 };
1932
1933 static int send_finished(sd_bus *bus, void *userdata) {
1934 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1935 usec_t *times = userdata;
1936 int r;
1937
1938 assert(bus);
1939 assert(times);
1940
1941 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
1942 if (r < 0)
1943 return r;
1944
1945 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
1946 if (r < 0)
1947 return r;
1948
1949 return sd_bus_send(bus, message, NULL);
1950 }
1951
1952 void bus_manager_send_finished(
1953 Manager *m,
1954 usec_t firmware_usec,
1955 usec_t loader_usec,
1956 usec_t kernel_usec,
1957 usec_t initrd_usec,
1958 usec_t userspace_usec,
1959 usec_t total_usec) {
1960
1961 int r;
1962
1963 assert(m);
1964
1965 r = bus_foreach_bus(
1966 m,
1967 NULL,
1968 send_finished,
1969 (usec_t[6]) {
1970 firmware_usec,
1971 loader_usec,
1972 kernel_usec,
1973 initrd_usec,
1974 userspace_usec,
1975 total_usec
1976 });
1977 if (r < 0)
1978 log_debug("Failed to send finished signal: %s", strerror(-r));
1979 }
1980
1981 static int send_reloading(sd_bus *bus, void *userdata) {
1982 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1983 int r;
1984
1985 assert(bus);
1986
1987 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
1988 if (r < 0)
1989 return r;
1990
1991 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
1992 if (r < 0)
1993 return r;
1994
1995 return sd_bus_send(bus, message, NULL);
1996 }
1997
1998 void bus_manager_send_reloading(Manager *m, bool active) {
1999 int r;
2000
2001 assert(m);
2002
2003 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2004 if (r < 0)
2005 log_debug("Failed to send reloading signal: %s", strerror(-r));
2006
2007 }