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