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