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