]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-manager.c
core: add new DefaultTasksMax= setting for system.conf
[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 "alloc-util.h"
27 #include "architecture.h"
28 #include "build.h"
29 #include "bus-common-errors.h"
30 #include "clock-util.h"
31 #include "dbus-execute.h"
32 #include "dbus-job.h"
33 #include "dbus-manager.h"
34 #include "dbus-unit.h"
35 #include "dbus.h"
36 #include "env-util.h"
37 #include "fd-util.h"
38 #include "fileio.h"
39 #include "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_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1104 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
1105 }
1106
1107 static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1108 Manager *m = userdata;
1109 int r;
1110
1111 assert(message);
1112 assert(m);
1113
1114 r = mac_selinux_access_check(message, "reload", error);
1115 if (r < 0)
1116 return r;
1117
1118 r = bus_verify_reload_daemon_async(m, message, error);
1119 if (r < 0)
1120 return r;
1121 if (r == 0)
1122 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1123
1124 /* Instead of sending the reply back right away, we just
1125 * remember that we need to and then send it after the reload
1126 * is finished. That way the caller knows when the reload
1127 * finished. */
1128
1129 assert(!m->queued_message);
1130 r = sd_bus_message_new_method_return(message, &m->queued_message);
1131 if (r < 0)
1132 return r;
1133
1134 m->exit_code = MANAGER_RELOAD;
1135
1136 return 1;
1137 }
1138
1139 static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1140 Manager *m = userdata;
1141 int r;
1142
1143 assert(message);
1144 assert(m);
1145
1146 r = mac_selinux_access_check(message, "reload", error);
1147 if (r < 0)
1148 return r;
1149
1150 r = bus_verify_reload_daemon_async(m, message, error);
1151 if (r < 0)
1152 return r;
1153 if (r == 0)
1154 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1155
1156 /* We don't send a reply back here, the client should
1157 * just wait for us disconnecting. */
1158
1159 m->exit_code = MANAGER_REEXECUTE;
1160 return 1;
1161 }
1162
1163 static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1164 Manager *m = userdata;
1165 int r;
1166
1167 assert(message);
1168 assert(m);
1169
1170 r = mac_selinux_access_check(message, "halt", error);
1171 if (r < 0)
1172 return r;
1173
1174 /* Exit() (in contrast to SetExitCode()) is actually allowed even if
1175 * we are running on the host. It will fall back on reboot() in
1176 * systemd-shutdown if it cannot do the exit() because it isn't a
1177 * container. */
1178
1179 m->exit_code = MANAGER_EXIT;
1180
1181 return sd_bus_reply_method_return(message, NULL);
1182 }
1183
1184 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1185 Manager *m = userdata;
1186 int r;
1187
1188 assert(message);
1189 assert(m);
1190
1191 r = mac_selinux_access_check(message, "reboot", error);
1192 if (r < 0)
1193 return r;
1194
1195 if (m->running_as != MANAGER_SYSTEM)
1196 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1197
1198 m->exit_code = MANAGER_REBOOT;
1199
1200 return sd_bus_reply_method_return(message, NULL);
1201 }
1202
1203 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1204 Manager *m = userdata;
1205 int r;
1206
1207 assert(message);
1208 assert(m);
1209
1210 r = mac_selinux_access_check(message, "halt", error);
1211 if (r < 0)
1212 return r;
1213
1214 if (m->running_as != MANAGER_SYSTEM)
1215 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1216
1217 m->exit_code = MANAGER_POWEROFF;
1218
1219 return sd_bus_reply_method_return(message, NULL);
1220 }
1221
1222 static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1223 Manager *m = userdata;
1224 int r;
1225
1226 assert(message);
1227 assert(m);
1228
1229 r = mac_selinux_access_check(message, "halt", error);
1230 if (r < 0)
1231 return r;
1232
1233 if (m->running_as != MANAGER_SYSTEM)
1234 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1235
1236 m->exit_code = MANAGER_HALT;
1237
1238 return sd_bus_reply_method_return(message, NULL);
1239 }
1240
1241 static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1242 Manager *m = userdata;
1243 int r;
1244
1245 assert(message);
1246 assert(m);
1247
1248 r = mac_selinux_access_check(message, "reboot", error);
1249 if (r < 0)
1250 return r;
1251
1252 if (m->running_as != MANAGER_SYSTEM)
1253 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1254
1255 m->exit_code = MANAGER_KEXEC;
1256
1257 return sd_bus_reply_method_return(message, NULL);
1258 }
1259
1260 static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1261 char *ri = NULL, *rt = NULL;
1262 const char *root, *init;
1263 Manager *m = userdata;
1264 int r;
1265
1266 assert(message);
1267 assert(m);
1268
1269 r = mac_selinux_access_check(message, "reboot", error);
1270 if (r < 0)
1271 return r;
1272
1273 if (m->running_as != MANAGER_SYSTEM)
1274 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1275
1276 r = sd_bus_message_read(message, "ss", &root, &init);
1277 if (r < 0)
1278 return r;
1279
1280 if (path_equal(root, "/") || !path_is_absolute(root))
1281 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1282
1283 /* Safety check */
1284 if (isempty(init)) {
1285 if (!path_is_os_tree(root))
1286 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);
1287 } else {
1288 _cleanup_free_ char *p = NULL;
1289
1290 if (!path_is_absolute(init))
1291 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1292
1293 p = strappend(root, init);
1294 if (!p)
1295 return -ENOMEM;
1296
1297 if (access(p, X_OK) < 0)
1298 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1299 }
1300
1301 rt = strdup(root);
1302 if (!rt)
1303 return -ENOMEM;
1304
1305 if (!isempty(init)) {
1306 ri = strdup(init);
1307 if (!ri) {
1308 free(rt);
1309 return -ENOMEM;
1310 }
1311 }
1312
1313 free(m->switch_root);
1314 m->switch_root = rt;
1315
1316 free(m->switch_root_init);
1317 m->switch_root_init = ri;
1318
1319 m->exit_code = MANAGER_SWITCH_ROOT;
1320
1321 return sd_bus_reply_method_return(message, NULL);
1322 }
1323
1324 static int method_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1325 _cleanup_strv_free_ char **plus = NULL;
1326 Manager *m = userdata;
1327 int r;
1328
1329 assert(message);
1330 assert(m);
1331
1332 r = mac_selinux_access_check(message, "reload", error);
1333 if (r < 0)
1334 return r;
1335
1336 r = sd_bus_message_read_strv(message, &plus);
1337 if (r < 0)
1338 return r;
1339 if (!strv_env_is_valid(plus))
1340 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1341
1342 r = bus_verify_set_environment_async(m, message, error);
1343 if (r < 0)
1344 return r;
1345 if (r == 0)
1346 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1347
1348 r = manager_environment_add(m, NULL, plus);
1349 if (r < 0)
1350 return r;
1351
1352 return sd_bus_reply_method_return(message, NULL);
1353 }
1354
1355 static int method_unset_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1356 _cleanup_strv_free_ char **minus = NULL;
1357 Manager *m = userdata;
1358 int r;
1359
1360 assert(message);
1361 assert(m);
1362
1363 r = mac_selinux_access_check(message, "reload", error);
1364 if (r < 0)
1365 return r;
1366
1367 r = sd_bus_message_read_strv(message, &minus);
1368 if (r < 0)
1369 return r;
1370
1371 if (!strv_env_name_or_assignment_is_valid(minus))
1372 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1373
1374 r = bus_verify_set_environment_async(m, message, error);
1375 if (r < 0)
1376 return r;
1377 if (r == 0)
1378 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1379
1380 r = manager_environment_add(m, minus, NULL);
1381 if (r < 0)
1382 return r;
1383
1384 return sd_bus_reply_method_return(message, NULL);
1385 }
1386
1387 static int method_unset_and_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1388 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1389 Manager *m = userdata;
1390 int r;
1391
1392 assert(message);
1393 assert(m);
1394
1395 r = mac_selinux_access_check(message, "reload", error);
1396 if (r < 0)
1397 return r;
1398
1399 r = sd_bus_message_read_strv(message, &minus);
1400 if (r < 0)
1401 return r;
1402
1403 r = sd_bus_message_read_strv(message, &plus);
1404 if (r < 0)
1405 return r;
1406
1407 if (!strv_env_name_or_assignment_is_valid(minus))
1408 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1409 if (!strv_env_is_valid(plus))
1410 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1411
1412 r = bus_verify_set_environment_async(m, message, error);
1413 if (r < 0)
1414 return r;
1415 if (r == 0)
1416 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1417
1418 r = manager_environment_add(m, minus, plus);
1419 if (r < 0)
1420 return r;
1421
1422 return sd_bus_reply_method_return(message, NULL);
1423 }
1424
1425 static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1426 uint8_t code;
1427 Manager *m = userdata;
1428 int r;
1429
1430 assert(message);
1431 assert(m);
1432
1433 r = mac_selinux_access_check(message, "exit", error);
1434 if (r < 0)
1435 return r;
1436
1437 r = sd_bus_message_read_basic(message, 'y', &code);
1438 if (r < 0)
1439 return r;
1440
1441 if (m->running_as == MANAGER_SYSTEM && detect_container() <= 0)
1442 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "ExitCode can only be set for user service managers or in containers.");
1443
1444 m->return_value = code;
1445
1446 return sd_bus_reply_method_return(message, NULL);
1447 }
1448
1449 static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1450 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1451 Manager *m = userdata;
1452 UnitFileList *item;
1453 Hashmap *h;
1454 Iterator i;
1455 int r;
1456
1457 assert(message);
1458 assert(m);
1459
1460 /* Anyone can call this method */
1461
1462 r = mac_selinux_access_check(message, "status", error);
1463 if (r < 0)
1464 return r;
1465
1466 r = sd_bus_message_new_method_return(message, &reply);
1467 if (r < 0)
1468 return r;
1469
1470 h = hashmap_new(&string_hash_ops);
1471 if (!h)
1472 return -ENOMEM;
1473
1474 r = unit_file_get_list(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1475 if (r < 0)
1476 goto fail;
1477
1478 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1479 if (r < 0)
1480 goto fail;
1481
1482 HASHMAP_FOREACH(item, h, i) {
1483
1484 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1485 if (r < 0)
1486 goto fail;
1487 }
1488
1489 unit_file_list_free(h);
1490
1491 r = sd_bus_message_close_container(reply);
1492 if (r < 0)
1493 return r;
1494
1495 return sd_bus_send(NULL, reply, NULL);
1496
1497 fail:
1498 unit_file_list_free(h);
1499 return r;
1500 }
1501
1502 static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1503 Manager *m = userdata;
1504 const char *name;
1505 UnitFileState state;
1506 UnitFileScope scope;
1507 int r;
1508
1509 assert(message);
1510 assert(m);
1511
1512 /* Anyone can call this method */
1513
1514 r = mac_selinux_access_check(message, "status", error);
1515 if (r < 0)
1516 return r;
1517
1518 r = sd_bus_message_read(message, "s", &name);
1519 if (r < 0)
1520 return r;
1521
1522 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1523
1524 r = unit_file_get_state(scope, NULL, name, &state);
1525 if (r < 0)
1526 return r;
1527
1528 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1529 }
1530
1531 static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1532 _cleanup_free_ char *default_target = NULL;
1533 Manager *m = userdata;
1534 UnitFileScope scope;
1535 int r;
1536
1537 assert(message);
1538 assert(m);
1539
1540 /* Anyone can call this method */
1541
1542 r = mac_selinux_access_check(message, "status", error);
1543 if (r < 0)
1544 return r;
1545
1546 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1547
1548 r = unit_file_get_default(scope, NULL, &default_target);
1549 if (r < 0)
1550 return r;
1551
1552 return sd_bus_reply_method_return(message, "s", default_target);
1553 }
1554
1555 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1556 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1557 int r;
1558
1559 assert(bus);
1560
1561 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1562 if (r < 0)
1563 return r;
1564
1565 return sd_bus_send(bus, message, NULL);
1566 }
1567
1568 static int reply_unit_file_changes_and_free(
1569 Manager *m,
1570 sd_bus_message *message,
1571 int carries_install_info,
1572 UnitFileChange *changes,
1573 unsigned n_changes) {
1574
1575 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1576 unsigned i;
1577 int r;
1578
1579 if (n_changes > 0) {
1580 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1581 if (r < 0)
1582 log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
1583 }
1584
1585 r = sd_bus_message_new_method_return(message, &reply);
1586 if (r < 0)
1587 goto fail;
1588
1589 if (carries_install_info >= 0) {
1590 r = sd_bus_message_append(reply, "b", carries_install_info);
1591 if (r < 0)
1592 goto fail;
1593 }
1594
1595 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1596 if (r < 0)
1597 goto fail;
1598
1599 for (i = 0; i < n_changes; i++) {
1600 r = sd_bus_message_append(
1601 reply, "(sss)",
1602 unit_file_change_type_to_string(changes[i].type),
1603 changes[i].path,
1604 changes[i].source);
1605 if (r < 0)
1606 goto fail;
1607 }
1608
1609 r = sd_bus_message_close_container(reply);
1610 if (r < 0)
1611 goto fail;
1612
1613 return sd_bus_send(NULL, reply, NULL);
1614
1615 fail:
1616 unit_file_changes_free(changes, n_changes);
1617 return r;
1618 }
1619
1620 static int method_enable_unit_files_generic(
1621 sd_bus_message *message,
1622 Manager *m,
1623 const char *verb,
1624 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1625 bool carries_install_info,
1626 sd_bus_error *error) {
1627
1628 _cleanup_strv_free_ char **l = NULL;
1629 UnitFileChange *changes = NULL;
1630 unsigned n_changes = 0;
1631 UnitFileScope scope;
1632 int runtime, force, r;
1633
1634 assert(message);
1635 assert(m);
1636
1637 r = sd_bus_message_read_strv(message, &l);
1638 if (r < 0)
1639 return r;
1640
1641 r = sd_bus_message_read(message, "bb", &runtime, &force);
1642 if (r < 0)
1643 return r;
1644
1645 r = bus_verify_manage_unit_files_async(m, message, error);
1646 if (r < 0)
1647 return r;
1648 if (r == 0)
1649 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1650
1651 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1652
1653 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1654 if (r == -ESHUTDOWN)
1655 return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked");
1656 if (r < 0)
1657 return r;
1658
1659 return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes);
1660 }
1661
1662 static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1663 return method_enable_unit_files_generic(message, userdata, "enable", unit_file_enable, true, error);
1664 }
1665
1666 static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1667 return method_enable_unit_files_generic(message, userdata, "enable", unit_file_reenable, true, error);
1668 }
1669
1670 static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1671 return method_enable_unit_files_generic(message, userdata, "enable", unit_file_link, false, error);
1672 }
1673
1674 static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1675 return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1676 }
1677
1678 static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1679 return method_enable_unit_files_generic(message, userdata, "enable", unit_file_preset_without_mode, true, error);
1680 }
1681
1682 static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1683 return method_enable_unit_files_generic(message, userdata, "disable", unit_file_mask, false, error);
1684 }
1685
1686 static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1687
1688 _cleanup_strv_free_ char **l = NULL;
1689 UnitFileChange *changes = NULL;
1690 unsigned n_changes = 0;
1691 Manager *m = userdata;
1692 UnitFilePresetMode mm;
1693 UnitFileScope scope;
1694 int runtime, force, r;
1695 const char *mode;
1696
1697 assert(message);
1698 assert(m);
1699
1700 r = sd_bus_message_read_strv(message, &l);
1701 if (r < 0)
1702 return r;
1703
1704 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1705 if (r < 0)
1706 return r;
1707
1708 if (isempty(mode))
1709 mm = UNIT_FILE_PRESET_FULL;
1710 else {
1711 mm = unit_file_preset_mode_from_string(mode);
1712 if (mm < 0)
1713 return -EINVAL;
1714 }
1715
1716 r = bus_verify_manage_unit_files_async(m, message, error);
1717 if (r < 0)
1718 return r;
1719 if (r == 0)
1720 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1721
1722 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1723
1724 r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
1725 if (r < 0)
1726 return r;
1727
1728 return reply_unit_file_changes_and_free(m, message, r, changes, n_changes);
1729 }
1730
1731 static int method_disable_unit_files_generic(
1732 sd_bus_message *message,
1733 Manager *m, const
1734 char *verb,
1735 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1736 sd_bus_error *error) {
1737
1738 _cleanup_strv_free_ char **l = NULL;
1739 UnitFileChange *changes = NULL;
1740 unsigned n_changes = 0;
1741 UnitFileScope scope;
1742 int r, runtime;
1743
1744 assert(message);
1745 assert(m);
1746
1747 r = sd_bus_message_read_strv(message, &l);
1748 if (r < 0)
1749 return r;
1750
1751 r = sd_bus_message_read(message, "b", &runtime);
1752 if (r < 0)
1753 return r;
1754
1755 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1756
1757 r = bus_verify_manage_unit_files_async(m, message, error);
1758 if (r < 0)
1759 return r;
1760 if (r == 0)
1761 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1762
1763 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1764 if (r < 0)
1765 return r;
1766
1767 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
1768 }
1769
1770 static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1771 return method_disable_unit_files_generic(message, userdata, "disable", unit_file_disable, error);
1772 }
1773
1774 static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1775 return method_disable_unit_files_generic(message, userdata, "enable", unit_file_unmask, error);
1776 }
1777
1778 static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1779 UnitFileChange *changes = NULL;
1780 unsigned n_changes = 0;
1781 Manager *m = userdata;
1782 UnitFileScope scope;
1783 const char *name;
1784 int force, r;
1785
1786 assert(message);
1787 assert(m);
1788
1789 r = mac_selinux_access_check(message, "enable", error);
1790 if (r < 0)
1791 return r;
1792
1793 r = sd_bus_message_read(message, "sb", &name, &force);
1794 if (r < 0)
1795 return r;
1796
1797 r = bus_verify_manage_unit_files_async(m, message, error);
1798 if (r < 0)
1799 return r;
1800 if (r == 0)
1801 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1802
1803 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1804
1805 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1806 if (r < 0)
1807 return r;
1808
1809 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
1810 }
1811
1812 static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1813 UnitFileChange *changes = NULL;
1814 unsigned n_changes = 0;
1815 Manager *m = userdata;
1816 UnitFilePresetMode mm;
1817 UnitFileScope scope;
1818 const char *mode;
1819 int force, runtime, r;
1820
1821 assert(message);
1822 assert(m);
1823
1824 r = mac_selinux_access_check(message, "enable", error);
1825 if (r < 0)
1826 return r;
1827
1828 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1829 if (r < 0)
1830 return r;
1831
1832 if (isempty(mode))
1833 mm = UNIT_FILE_PRESET_FULL;
1834 else {
1835 mm = unit_file_preset_mode_from_string(mode);
1836 if (mm < 0)
1837 return -EINVAL;
1838 }
1839
1840 r = bus_verify_manage_unit_files_async(m, message, error);
1841 if (r < 0)
1842 return r;
1843 if (r == 0)
1844 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1845
1846 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1847
1848 r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
1849 if (r < 0)
1850 return r;
1851
1852 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
1853 }
1854
1855 static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1856 _cleanup_strv_free_ char **l = NULL;
1857 Manager *m = userdata;
1858 UnitFileChange *changes = NULL;
1859 unsigned n_changes = 0;
1860 UnitFileScope scope;
1861 int runtime, force, r;
1862 char *target;
1863 char *type;
1864 UnitDependency dep;
1865
1866 assert(message);
1867 assert(m);
1868
1869 r = bus_verify_manage_unit_files_async(m, message, error);
1870 if (r < 0)
1871 return r;
1872 if (r == 0)
1873 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1874
1875 r = sd_bus_message_read_strv(message, &l);
1876 if (r < 0)
1877 return r;
1878
1879 r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
1880 if (r < 0)
1881 return r;
1882
1883 dep = unit_dependency_from_string(type);
1884 if (dep < 0)
1885 return -EINVAL;
1886
1887 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1888
1889 r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
1890 if (r == -ESHUTDOWN)
1891 return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked");
1892 if (r < 0)
1893 return r;
1894
1895 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
1896 }
1897
1898 const sd_bus_vtable bus_manager_vtable[] = {
1899 SD_BUS_VTABLE_START(0),
1900
1901 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1902 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1903 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1904 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1905 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1906 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1907 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1908 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1909 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1910 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1911 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1912 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1913 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1914 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1915 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1916 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1917 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1918 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1919 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1920 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1921 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1922 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1923 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1924 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1925 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1926 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1927 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1928 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1929 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1930 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1931 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1932 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1933 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1934 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1935 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
1936 SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0),
1937 SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec, offsetof(Manager, default_timer_accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1938 SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1939 SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1940 SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1941 SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
1942 SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
1943 SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1944 SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1945 SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, default_memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1946 SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, default_tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1947 SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
1948 SD_BUS_PROPERTY("DefaultLimitFSIZE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
1949 SD_BUS_PROPERTY("DefaultLimitDATA", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
1950 SD_BUS_PROPERTY("DefaultLimitSTACK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
1951 SD_BUS_PROPERTY("DefaultLimitCORE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
1952 SD_BUS_PROPERTY("DefaultLimitRSS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
1953 SD_BUS_PROPERTY("DefaultLimitNOFILE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
1954 SD_BUS_PROPERTY("DefaultLimitAS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
1955 SD_BUS_PROPERTY("DefaultLimitNPROC", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
1956 SD_BUS_PROPERTY("DefaultLimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
1957 SD_BUS_PROPERTY("DefaultLimitLOCKS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
1958 SD_BUS_PROPERTY("DefaultLimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
1959 SD_BUS_PROPERTY("DefaultLimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
1960 SD_BUS_PROPERTY("DefaultLimitNICE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
1961 SD_BUS_PROPERTY("DefaultLimitRTPRIO", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
1962 SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1963 SD_BUS_PROPERTY("DefaultTasksMax", "t", NULL, offsetof(Manager, default_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
1964 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1965
1966 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1967 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1968 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1969 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1970 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
1971 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1972 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1973 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1974 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1975 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1976 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1977 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1978 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1979 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
1980 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1981 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1982 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
1983 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1984 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
1985 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1986 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
1987 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1988 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1989 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1990 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1991 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
1992 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
1993 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
1994 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
1995 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1996 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1997 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1998 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1999 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2000 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2001 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2002 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2003 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2004 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2005 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
2006 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2007 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2008 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2009 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2010 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2011 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2012 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2013 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2014 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2015 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2016 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2017 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2018 SD_BUS_METHOD("SetExitCode", "y", NULL, method_set_exit_code, SD_BUS_VTABLE_UNPRIVILEGED),
2019
2020 SD_BUS_SIGNAL("UnitNew", "so", 0),
2021 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2022 SD_BUS_SIGNAL("JobNew", "uos", 0),
2023 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2024 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2025 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2026 SD_BUS_SIGNAL("Reloading", "b", 0),
2027
2028 SD_BUS_VTABLE_END
2029 };
2030
2031 static int send_finished(sd_bus *bus, void *userdata) {
2032 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2033 usec_t *times = userdata;
2034 int r;
2035
2036 assert(bus);
2037 assert(times);
2038
2039 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2040 if (r < 0)
2041 return r;
2042
2043 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2044 if (r < 0)
2045 return r;
2046
2047 return sd_bus_send(bus, message, NULL);
2048 }
2049
2050 void bus_manager_send_finished(
2051 Manager *m,
2052 usec_t firmware_usec,
2053 usec_t loader_usec,
2054 usec_t kernel_usec,
2055 usec_t initrd_usec,
2056 usec_t userspace_usec,
2057 usec_t total_usec) {
2058
2059 int r;
2060
2061 assert(m);
2062
2063 r = bus_foreach_bus(
2064 m,
2065 NULL,
2066 send_finished,
2067 (usec_t[6]) {
2068 firmware_usec,
2069 loader_usec,
2070 kernel_usec,
2071 initrd_usec,
2072 userspace_usec,
2073 total_usec
2074 });
2075 if (r < 0)
2076 log_debug_errno(r, "Failed to send finished signal: %m");
2077 }
2078
2079 static int send_reloading(sd_bus *bus, void *userdata) {
2080 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2081 int r;
2082
2083 assert(bus);
2084
2085 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2086 if (r < 0)
2087 return r;
2088
2089 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2090 if (r < 0)
2091 return r;
2092
2093 return sd_bus_send(bus, message, NULL);
2094 }
2095
2096 void bus_manager_send_reloading(Manager *m, bool active) {
2097 int r;
2098
2099 assert(m);
2100
2101 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2102 if (r < 0)
2103 log_debug_errno(r, "Failed to send reloading signal: %m");
2104 }
2105
2106 static int send_changed_signal(sd_bus *bus, void *userdata) {
2107 assert(bus);
2108
2109 return sd_bus_emit_properties_changed_strv(bus,
2110 "/org/freedesktop/systemd1",
2111 "org.freedesktop.systemd1.Manager",
2112 NULL);
2113 }
2114
2115 void bus_manager_send_change_signal(Manager *m) {
2116 int r;
2117
2118 assert(m);
2119
2120 r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
2121 if (r < 0)
2122 log_debug_errno(r, "Failed to send manager change signal: %m");
2123 }