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