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