]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-unit.c
Merge pull request #13076 from keszybz/pr/13062
[thirdparty/systemd.git] / src / core / dbus-unit.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2
3 #include "sd-bus.h"
4
5 #include "alloc-util.h"
6 #include "bpf-firewall.h"
7 #include "bus-common-errors.h"
8 #include "cgroup-util.h"
9 #include "condition.h"
10 #include "dbus-job.h"
11 #include "dbus-unit.h"
12 #include "dbus-util.h"
13 #include "dbus.h"
14 #include "fd-util.h"
15 #include "locale-util.h"
16 #include "log.h"
17 #include "path-util.h"
18 #include "process-util.h"
19 #include "selinux-access.h"
20 #include "signal-util.h"
21 #include "special.h"
22 #include "string-table.h"
23 #include "string-util.h"
24 #include "strv.h"
25 #include "user-util.h"
26 #include "web-util.h"
27
28 static bool unit_can_start_refuse_manual(Unit *u) {
29 return unit_can_start(u) && !u->refuse_manual_start;
30 }
31
32 static bool unit_can_stop_refuse_manual(Unit *u) {
33 return unit_can_stop(u) && !u->refuse_manual_stop;
34 }
35
36 static bool unit_can_isolate_refuse_manual(Unit *u) {
37 return unit_can_isolate(u) && !u->refuse_manual_start;
38 }
39
40 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
41 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
42 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
43 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
44 static BUS_DEFINE_PROPERTY_GET(property_get_description, "s", Unit, unit_description);
45 static BUS_DEFINE_PROPERTY_GET2(property_get_active_state, "s", Unit, unit_active_state, unit_active_state_to_string);
46 static BUS_DEFINE_PROPERTY_GET(property_get_sub_state, "s", Unit, unit_sub_state_to_string);
47 static BUS_DEFINE_PROPERTY_GET2(property_get_unit_file_state, "s", Unit, unit_get_unit_file_state, unit_file_state_to_string);
48 static BUS_DEFINE_PROPERTY_GET(property_get_can_reload, "b", Unit, unit_can_reload);
49 static BUS_DEFINE_PROPERTY_GET(property_get_can_start, "b", Unit, unit_can_start_refuse_manual);
50 static BUS_DEFINE_PROPERTY_GET(property_get_can_stop, "b", Unit, unit_can_stop_refuse_manual);
51 static BUS_DEFINE_PROPERTY_GET(property_get_can_isolate, "b", Unit, unit_can_isolate_refuse_manual);
52 static BUS_DEFINE_PROPERTY_GET(property_get_need_daemon_reload, "b", Unit, unit_need_daemon_reload);
53 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_strv, "as", 0);
54
55 static int property_get_can_clean(
56 sd_bus *bus,
57 const char *path,
58 const char *interface,
59 const char *property,
60 sd_bus_message *reply,
61 void *userdata,
62 sd_bus_error *error) {
63
64 Unit *u = userdata;
65 ExecCleanMask mask;
66 int r;
67
68 assert(bus);
69 assert(reply);
70
71 r = unit_can_clean(u, &mask);
72 if (r < 0)
73 return r;
74
75 r = sd_bus_message_open_container(reply, 'a', "s");
76 if (r < 0)
77 return r;
78
79 for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
80 if (!FLAGS_SET(mask, 1U << t))
81 continue;
82
83 r = sd_bus_message_append(reply, "s", exec_resource_type_to_string(t));
84 if (r < 0)
85 return r;
86 }
87
88 return sd_bus_message_close_container(reply);
89 }
90
91 static int property_get_names(
92 sd_bus *bus,
93 const char *path,
94 const char *interface,
95 const char *property,
96 sd_bus_message *reply,
97 void *userdata,
98 sd_bus_error *error) {
99
100 Set **s = userdata;
101 Iterator i;
102 const char *t;
103 int r;
104
105 assert(bus);
106 assert(reply);
107 assert(s);
108
109 r = sd_bus_message_open_container(reply, 'a', "s");
110 if (r < 0)
111 return r;
112
113 SET_FOREACH(t, *s, i) {
114 r = sd_bus_message_append(reply, "s", t);
115 if (r < 0)
116 return r;
117 }
118
119 return sd_bus_message_close_container(reply);
120 }
121
122 static int property_get_following(
123 sd_bus *bus,
124 const char *path,
125 const char *interface,
126 const char *property,
127 sd_bus_message *reply,
128 void *userdata,
129 sd_bus_error *error) {
130
131 Unit *u = userdata, *f;
132
133 assert(bus);
134 assert(reply);
135 assert(u);
136
137 f = unit_following(u);
138 return sd_bus_message_append(reply, "s", f ? f->id : NULL);
139 }
140
141 static int property_get_dependencies(
142 sd_bus *bus,
143 const char *path,
144 const char *interface,
145 const char *property,
146 sd_bus_message *reply,
147 void *userdata,
148 sd_bus_error *error) {
149
150 Hashmap **h = userdata;
151 Iterator j;
152 Unit *u;
153 void *v;
154 int r;
155
156 assert(bus);
157 assert(reply);
158 assert(h);
159
160 r = sd_bus_message_open_container(reply, 'a', "s");
161 if (r < 0)
162 return r;
163
164 HASHMAP_FOREACH_KEY(v, u, *h, j) {
165 r = sd_bus_message_append(reply, "s", u->id);
166 if (r < 0)
167 return r;
168 }
169
170 return sd_bus_message_close_container(reply);
171 }
172
173 static int property_get_requires_mounts_for(
174 sd_bus *bus,
175 const char *path,
176 const char *interface,
177 const char *property,
178 sd_bus_message *reply,
179 void *userdata,
180 sd_bus_error *error) {
181
182 Hashmap **h = userdata;
183 const char *p;
184 Iterator j;
185 void *v;
186 int r;
187
188 assert(bus);
189 assert(reply);
190 assert(h);
191
192 r = sd_bus_message_open_container(reply, 'a', "s");
193 if (r < 0)
194 return r;
195
196 HASHMAP_FOREACH_KEY(v, p, *h, j) {
197 r = sd_bus_message_append(reply, "s", p);
198 if (r < 0)
199 return r;
200 }
201
202 return sd_bus_message_close_container(reply);
203 }
204
205 static int property_get_unit_file_preset(
206 sd_bus *bus,
207 const char *path,
208 const char *interface,
209 const char *property,
210 sd_bus_message *reply,
211 void *userdata,
212 sd_bus_error *error) {
213
214 Unit *u = userdata;
215 int r;
216
217 assert(bus);
218 assert(reply);
219 assert(u);
220
221 r = unit_get_unit_file_preset(u);
222
223 return sd_bus_message_append(reply, "s",
224 r < 0 ? NULL:
225 r > 0 ? "enabled" : "disabled");
226 }
227
228 static int property_get_job(
229 sd_bus *bus,
230 const char *path,
231 const char *interface,
232 const char *property,
233 sd_bus_message *reply,
234 void *userdata,
235 sd_bus_error *error) {
236
237 _cleanup_free_ char *p = NULL;
238 Job **j = userdata;
239
240 assert(bus);
241 assert(reply);
242 assert(j);
243
244 if (!*j)
245 return sd_bus_message_append(reply, "(uo)", 0, "/");
246
247 p = job_dbus_path(*j);
248 if (!p)
249 return -ENOMEM;
250
251 return sd_bus_message_append(reply, "(uo)", (*j)->id, p);
252 }
253
254 static int property_get_conditions(
255 sd_bus *bus,
256 const char *path,
257 const char *interface,
258 const char *property,
259 sd_bus_message *reply,
260 void *userdata,
261 sd_bus_error *error) {
262
263 const char *(*to_string)(ConditionType type) = NULL;
264 Condition **list = userdata, *c;
265 int r;
266
267 assert(bus);
268 assert(reply);
269 assert(list);
270
271 to_string = streq(property, "Asserts") ? assert_type_to_string : condition_type_to_string;
272
273 r = sd_bus_message_open_container(reply, 'a', "(sbbsi)");
274 if (r < 0)
275 return r;
276
277 LIST_FOREACH(conditions, c, *list) {
278 int tristate;
279
280 tristate =
281 c->result == CONDITION_UNTESTED ? 0 :
282 c->result == CONDITION_SUCCEEDED ? 1 : -1;
283
284 r = sd_bus_message_append(reply, "(sbbsi)",
285 to_string(c->type),
286 c->trigger, c->negate,
287 c->parameter, tristate);
288 if (r < 0)
289 return r;
290
291 }
292
293 return sd_bus_message_close_container(reply);
294 }
295
296 static int property_get_load_error(
297 sd_bus *bus,
298 const char *path,
299 const char *interface,
300 const char *property,
301 sd_bus_message *reply,
302 void *userdata,
303 sd_bus_error *error) {
304
305 _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
306 Unit *u = userdata;
307 int r;
308
309 assert(bus);
310 assert(reply);
311 assert(u);
312
313 r = bus_unit_validate_load_state(u, &e);
314 if (r < 0)
315 return sd_bus_message_append(reply, "(ss)", e.name, e.message);
316
317 return sd_bus_message_append(reply, "(ss)", NULL, NULL);
318 }
319
320 static int bus_verify_manage_units_async_full(
321 Unit *u,
322 const char *verb,
323 int capability,
324 const char *polkit_message,
325 bool interactive,
326 sd_bus_message *call,
327 sd_bus_error *error) {
328
329 const char *details[9] = {
330 "unit", u->id,
331 "verb", verb,
332 };
333
334 if (polkit_message) {
335 details[4] = "polkit.message";
336 details[5] = polkit_message;
337 details[6] = "polkit.gettext_domain";
338 details[7] = GETTEXT_PACKAGE;
339 }
340
341 return bus_verify_polkit_async(
342 call,
343 capability,
344 "org.freedesktop.systemd1.manage-units",
345 details,
346 interactive,
347 UID_INVALID,
348 &u->manager->polkit_registry,
349 error);
350 }
351
352 static const char *const polkit_message_for_job[_JOB_TYPE_MAX] = {
353 [JOB_START] = N_("Authentication is required to start '$(unit)'."),
354 [JOB_STOP] = N_("Authentication is required to stop '$(unit)'."),
355 [JOB_RELOAD] = N_("Authentication is required to reload '$(unit)'."),
356 [JOB_RESTART] = N_("Authentication is required to restart '$(unit)'."),
357 [JOB_TRY_RESTART] = N_("Authentication is required to restart '$(unit)'."),
358 };
359
360 int bus_unit_method_start_generic(
361 sd_bus_message *message,
362 Unit *u,
363 JobType job_type,
364 bool reload_if_possible,
365 sd_bus_error *error) {
366
367 const char *smode, *verb;
368 JobMode mode;
369 int r;
370
371 assert(message);
372 assert(u);
373 assert(job_type >= 0 && job_type < _JOB_TYPE_MAX);
374
375 r = mac_selinux_unit_access_check(
376 u, message,
377 job_type_to_access_method(job_type),
378 error);
379 if (r < 0)
380 return r;
381
382 r = sd_bus_message_read(message, "s", &smode);
383 if (r < 0)
384 return r;
385
386 mode = job_mode_from_string(smode);
387 if (mode < 0)
388 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode);
389
390 if (reload_if_possible)
391 verb = strjoina("reload-or-", job_type_to_string(job_type));
392 else
393 verb = job_type_to_string(job_type);
394
395 r = bus_verify_manage_units_async_full(
396 u,
397 verb,
398 CAP_SYS_ADMIN,
399 polkit_message_for_job[job_type],
400 true,
401 message,
402 error);
403 if (r < 0)
404 return r;
405 if (r == 0)
406 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
407
408 return bus_unit_queue_job(message, u, job_type, mode,
409 reload_if_possible ? BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE : 0, error);
410 }
411
412 static int method_start(sd_bus_message *message, void *userdata, sd_bus_error *error) {
413 return bus_unit_method_start_generic(message, userdata, JOB_START, false, error);
414 }
415
416 static int method_stop(sd_bus_message *message, void *userdata, sd_bus_error *error) {
417 return bus_unit_method_start_generic(message, userdata, JOB_STOP, false, error);
418 }
419
420 static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
421 return bus_unit_method_start_generic(message, userdata, JOB_RELOAD, false, error);
422 }
423
424 static int method_restart(sd_bus_message *message, void *userdata, sd_bus_error *error) {
425 return bus_unit_method_start_generic(message, userdata, JOB_RESTART, false, error);
426 }
427
428 static int method_try_restart(sd_bus_message *message, void *userdata, sd_bus_error *error) {
429 return bus_unit_method_start_generic(message, userdata, JOB_TRY_RESTART, false, error);
430 }
431
432 static int method_reload_or_restart(sd_bus_message *message, void *userdata, sd_bus_error *error) {
433 return bus_unit_method_start_generic(message, userdata, JOB_RESTART, true, error);
434 }
435
436 static int method_reload_or_try_restart(sd_bus_message *message, void *userdata, sd_bus_error *error) {
437 return bus_unit_method_start_generic(message, userdata, JOB_TRY_RESTART, true, error);
438 }
439
440 int bus_unit_method_enqueue_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
441 BusUnitQueueFlags flags = BUS_UNIT_QUEUE_VERBOSE_REPLY;
442 const char *jtype, *smode;
443 Unit *u = userdata;
444 JobType type;
445 JobMode mode;
446 int r;
447
448 assert(message);
449 assert(u);
450
451 r = sd_bus_message_read(message, "ss", &jtype, &smode);
452 if (r < 0)
453 return r;
454
455 /* Parse the two magic reload types "reload-or-…" manually */
456 if (streq(jtype, "reload-or-restart")) {
457 type = JOB_RESTART;
458 flags |= BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE;
459 } else if (streq(jtype, "reload-or-try-restart")) {
460 type = JOB_TRY_RESTART;
461 flags |= BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE;
462 } else {
463 /* And the rest generically */
464 type = job_type_from_string(jtype);
465 if (type < 0)
466 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job type %s invalid", jtype);
467 }
468
469 mode = job_mode_from_string(smode);
470 if (mode < 0)
471 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode);
472
473 r = mac_selinux_unit_access_check(
474 u, message,
475 job_type_to_access_method(type),
476 error);
477 if (r < 0)
478 return r;
479
480 r = bus_verify_manage_units_async_full(
481 u,
482 jtype,
483 CAP_SYS_ADMIN,
484 polkit_message_for_job[type],
485 true,
486 message,
487 error);
488 if (r < 0)
489 return r;
490 if (r == 0)
491 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
492
493 return bus_unit_queue_job(message, u, type, mode, flags, error);
494 }
495
496 int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) {
497 Unit *u = userdata;
498 const char *swho;
499 int32_t signo;
500 KillWho who;
501 int r;
502
503 assert(message);
504 assert(u);
505
506 r = mac_selinux_unit_access_check(u, message, "stop", error);
507 if (r < 0)
508 return r;
509
510 r = sd_bus_message_read(message, "si", &swho, &signo);
511 if (r < 0)
512 return r;
513
514 if (isempty(swho))
515 who = KILL_ALL;
516 else {
517 who = kill_who_from_string(swho);
518 if (who < 0)
519 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument %s", swho);
520 }
521
522 if (!SIGNAL_VALID(signo))
523 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
524
525 r = bus_verify_manage_units_async_full(
526 u,
527 "kill",
528 CAP_KILL,
529 N_("Authentication is required to send a UNIX signal to the processes of '$(unit)'."),
530 true,
531 message,
532 error);
533 if (r < 0)
534 return r;
535 if (r == 0)
536 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
537
538 r = unit_kill(u, who, signo, error);
539 if (r < 0)
540 return r;
541
542 return sd_bus_reply_method_return(message, NULL);
543 }
544
545 int bus_unit_method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
546 Unit *u = userdata;
547 int r;
548
549 assert(message);
550 assert(u);
551
552 r = mac_selinux_unit_access_check(u, message, "reload", error);
553 if (r < 0)
554 return r;
555
556 r = bus_verify_manage_units_async_full(
557 u,
558 "reset-failed",
559 CAP_SYS_ADMIN,
560 N_("Authentication is required to reset the \"failed\" state of '$(unit)'."),
561 true,
562 message,
563 error);
564 if (r < 0)
565 return r;
566 if (r == 0)
567 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
568
569 unit_reset_failed(u);
570
571 return sd_bus_reply_method_return(message, NULL);
572 }
573
574 int bus_unit_method_set_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
575 Unit *u = userdata;
576 int runtime, r;
577
578 assert(message);
579 assert(u);
580
581 r = mac_selinux_unit_access_check(u, message, "start", error);
582 if (r < 0)
583 return r;
584
585 r = sd_bus_message_read(message, "b", &runtime);
586 if (r < 0)
587 return r;
588
589 r = bus_verify_manage_units_async_full(
590 u,
591 "set-property",
592 CAP_SYS_ADMIN,
593 N_("Authentication is required to set properties on '$(unit)'."),
594 true,
595 message,
596 error);
597 if (r < 0)
598 return r;
599 if (r == 0)
600 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
601
602 r = bus_unit_set_properties(u, message, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, true, error);
603 if (r < 0)
604 return r;
605
606 return sd_bus_reply_method_return(message, NULL);
607 }
608
609 int bus_unit_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error) {
610 Unit *u = userdata;
611 int r;
612
613 assert(message);
614 assert(u);
615
616 r = mac_selinux_unit_access_check(u, message, "start", error);
617 if (r < 0)
618 return r;
619
620 r = bus_verify_manage_units_async_full(
621 u,
622 "ref",
623 CAP_SYS_ADMIN,
624 NULL,
625 false,
626 message,
627 error);
628 if (r < 0)
629 return r;
630 if (r == 0)
631 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
632
633 r = bus_unit_track_add_sender(u, message);
634 if (r < 0)
635 return r;
636
637 return sd_bus_reply_method_return(message, NULL);
638 }
639
640 int bus_unit_method_unref(sd_bus_message *message, void *userdata, sd_bus_error *error) {
641 Unit *u = userdata;
642 int r;
643
644 assert(message);
645 assert(u);
646
647 r = bus_unit_track_remove_sender(u, message);
648 if (r == -EUNATCH)
649 return sd_bus_error_setf(error, BUS_ERROR_NOT_REFERENCED, "Unit has not been referenced yet.");
650 if (r < 0)
651 return r;
652
653 return sd_bus_reply_method_return(message, NULL);
654 }
655
656 int bus_unit_method_clean(sd_bus_message *message, void *userdata, sd_bus_error *error) {
657 ExecCleanMask mask = 0;
658 Unit *u = userdata;
659 int r;
660
661 assert(message);
662 assert(u);
663
664 r = mac_selinux_unit_access_check(u, message, "stop", error);
665 if (r < 0)
666 return r;
667
668 r = sd_bus_message_enter_container(message, 'a', "s");
669 if (r < 0)
670 return r;
671
672 for (;;) {
673 const char *i;
674
675 r = sd_bus_message_read(message, "s", &i);
676 if (r < 0)
677 return r;
678 if (r == 0)
679 break;
680
681 if (streq(i, "all"))
682 mask |= EXEC_CLEAN_ALL;
683 else {
684 ExecDirectoryType t;
685
686 t = exec_resource_type_from_string(i);
687 if (t < 0)
688 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid resource type: %s", i);
689
690 mask |= 1U << t;
691 }
692 }
693
694 r = sd_bus_message_exit_container(message);
695 if (r < 0)
696 return r;
697
698 r = bus_verify_manage_units_async_full(
699 u,
700 "clean",
701 CAP_DAC_OVERRIDE,
702 N_("Authentication is required to delete files and directories associated with '$(unit)'."),
703 true,
704 message,
705 error);
706 if (r < 0)
707 return r;
708 if (r == 0)
709 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
710
711 r = unit_clean(u, mask);
712 if (r == -EOPNOTSUPP)
713 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Unit '%s' does not supporting cleaning.", u->id);
714 if (r == -EUNATCH)
715 return sd_bus_error_setf(error, BUS_ERROR_NOTHING_TO_CLEAN, "No matching resources found.");
716 if (r == -EBUSY)
717 return sd_bus_error_setf(error, BUS_ERROR_UNIT_BUSY, "Unit is not inactive or has pending job.");
718 if (r < 0)
719 return r;
720
721 return sd_bus_reply_method_return(message, NULL);
722 }
723
724 static int property_get_refs(
725 sd_bus *bus,
726 const char *path,
727 const char *interface,
728 const char *property,
729 sd_bus_message *reply,
730 void *userdata,
731 sd_bus_error *error) {
732
733 Unit *u = userdata;
734 const char *i;
735 int r;
736
737 assert(bus);
738 assert(reply);
739
740 r = sd_bus_message_open_container(reply, 'a', "s");
741 if (r < 0)
742 return r;
743
744 for (i = sd_bus_track_first(u->bus_track); i; i = sd_bus_track_next(u->bus_track)) {
745 int c, k;
746
747 c = sd_bus_track_count_name(u->bus_track, i);
748 if (c < 0)
749 return c;
750
751 /* Add the item multiple times if the ref count for each is above 1 */
752 for (k = 0; k < c; k++) {
753 r = sd_bus_message_append(reply, "s", i);
754 if (r < 0)
755 return r;
756 }
757 }
758
759 return sd_bus_message_close_container(reply);
760 }
761
762 const sd_bus_vtable bus_unit_vtable[] = {
763 SD_BUS_VTABLE_START(0),
764
765 SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Unit, id), SD_BUS_VTABLE_PROPERTY_CONST),
766 SD_BUS_PROPERTY("Names", "as", property_get_names, offsetof(Unit, names), SD_BUS_VTABLE_PROPERTY_CONST),
767 SD_BUS_PROPERTY("Following", "s", property_get_following, 0, 0),
768 SD_BUS_PROPERTY("Requires", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRES]), SD_BUS_VTABLE_PROPERTY_CONST),
769 SD_BUS_PROPERTY("Requisite", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE]), SD_BUS_VTABLE_PROPERTY_CONST),
770 SD_BUS_PROPERTY("Wants", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_WANTS]), SD_BUS_VTABLE_PROPERTY_CONST),
771 SD_BUS_PROPERTY("BindsTo", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BINDS_TO]), SD_BUS_VTABLE_PROPERTY_CONST),
772 SD_BUS_PROPERTY("PartOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PART_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
773 SD_BUS_PROPERTY("RequiredBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
774 SD_BUS_PROPERTY("RequisiteOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
775 SD_BUS_PROPERTY("WantedBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_WANTED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
776 SD_BUS_PROPERTY("BoundBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BOUND_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
777 SD_BUS_PROPERTY("ConsistsOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
778 SD_BUS_PROPERTY("Conflicts", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONFLICTS]), SD_BUS_VTABLE_PROPERTY_CONST),
779 SD_BUS_PROPERTY("ConflictedBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
780 SD_BUS_PROPERTY("Before", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BEFORE]), SD_BUS_VTABLE_PROPERTY_CONST),
781 SD_BUS_PROPERTY("After", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_AFTER]), SD_BUS_VTABLE_PROPERTY_CONST),
782 SD_BUS_PROPERTY("OnFailure", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_ON_FAILURE]), SD_BUS_VTABLE_PROPERTY_CONST),
783 SD_BUS_PROPERTY("Triggers", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_TRIGGERS]), SD_BUS_VTABLE_PROPERTY_CONST),
784 SD_BUS_PROPERTY("TriggeredBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
785 SD_BUS_PROPERTY("PropagatesReloadTo", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), SD_BUS_VTABLE_PROPERTY_CONST),
786 SD_BUS_PROPERTY("ReloadPropagatedFrom", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), SD_BUS_VTABLE_PROPERTY_CONST),
787 SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_JOINS_NAMESPACE_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
788 SD_BUS_PROPERTY("RequiresMountsFor", "as", property_get_requires_mounts_for, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST),
789 SD_BUS_PROPERTY("Documentation", "as", NULL, offsetof(Unit, documentation), SD_BUS_VTABLE_PROPERTY_CONST),
790 SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST),
791 SD_BUS_PROPERTY("LoadState", "s", property_get_load_state, offsetof(Unit, load_state), SD_BUS_VTABLE_PROPERTY_CONST),
792 SD_BUS_PROPERTY("ActiveState", "s", property_get_active_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
793 SD_BUS_PROPERTY("SubState", "s", property_get_sub_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
794 SD_BUS_PROPERTY("FragmentPath", "s", NULL, offsetof(Unit, fragment_path), SD_BUS_VTABLE_PROPERTY_CONST),
795 SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Unit, source_path), SD_BUS_VTABLE_PROPERTY_CONST),
796 SD_BUS_PROPERTY("DropInPaths", "as", NULL, offsetof(Unit, dropin_paths), SD_BUS_VTABLE_PROPERTY_CONST),
797 SD_BUS_PROPERTY("UnitFileState", "s", property_get_unit_file_state, 0, 0),
798 SD_BUS_PROPERTY("UnitFilePreset", "s", property_get_unit_file_preset, 0, 0),
799 BUS_PROPERTY_DUAL_TIMESTAMP("StateChangeTimestamp", offsetof(Unit, state_change_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
800 BUS_PROPERTY_DUAL_TIMESTAMP("InactiveExitTimestamp", offsetof(Unit, inactive_exit_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
801 BUS_PROPERTY_DUAL_TIMESTAMP("ActiveEnterTimestamp", offsetof(Unit, active_enter_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
802 BUS_PROPERTY_DUAL_TIMESTAMP("ActiveExitTimestamp", offsetof(Unit, active_exit_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
803 BUS_PROPERTY_DUAL_TIMESTAMP("InactiveEnterTimestamp", offsetof(Unit, inactive_enter_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
804 SD_BUS_PROPERTY("CanStart", "b", property_get_can_start, 0, SD_BUS_VTABLE_PROPERTY_CONST),
805 SD_BUS_PROPERTY("CanStop", "b", property_get_can_stop, 0, SD_BUS_VTABLE_PROPERTY_CONST),
806 SD_BUS_PROPERTY("CanReload", "b", property_get_can_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
807 SD_BUS_PROPERTY("CanIsolate", "b", property_get_can_isolate, 0, SD_BUS_VTABLE_PROPERTY_CONST),
808 SD_BUS_PROPERTY("CanClean", "as", property_get_can_clean, 0, SD_BUS_VTABLE_PROPERTY_CONST),
809 SD_BUS_PROPERTY("Job", "(uo)", property_get_job, offsetof(Unit, job), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
810 SD_BUS_PROPERTY("StopWhenUnneeded", "b", bus_property_get_bool, offsetof(Unit, stop_when_unneeded), SD_BUS_VTABLE_PROPERTY_CONST),
811 SD_BUS_PROPERTY("RefuseManualStart", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_start), SD_BUS_VTABLE_PROPERTY_CONST),
812 SD_BUS_PROPERTY("RefuseManualStop", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_stop), SD_BUS_VTABLE_PROPERTY_CONST),
813 SD_BUS_PROPERTY("AllowIsolate", "b", bus_property_get_bool, offsetof(Unit, allow_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
814 SD_BUS_PROPERTY("DefaultDependencies", "b", bus_property_get_bool, offsetof(Unit, default_dependencies), SD_BUS_VTABLE_PROPERTY_CONST),
815 SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
816 SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
817 SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
818 SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
819 SD_BUS_PROPERTY("JobRunningTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_running_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
820 SD_BUS_PROPERTY("JobTimeoutAction", "s", property_get_emergency_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
821 SD_BUS_PROPERTY("JobTimeoutRebootArgument", "s", NULL, offsetof(Unit, job_timeout_reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
822 SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
823 SD_BUS_PROPERTY("AssertResult", "b", bus_property_get_bool, offsetof(Unit, assert_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
824 BUS_PROPERTY_DUAL_TIMESTAMP("ConditionTimestamp", offsetof(Unit, condition_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
825 BUS_PROPERTY_DUAL_TIMESTAMP("AssertTimestamp", offsetof(Unit, assert_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
826 SD_BUS_PROPERTY("Conditions", "a(sbbsi)", property_get_conditions, offsetof(Unit, conditions), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
827 SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
828 SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
829 SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
830 SD_BUS_PROPERTY("Perpetual", "b", bus_property_get_bool, offsetof(Unit, perpetual), SD_BUS_VTABLE_PROPERTY_CONST),
831 SD_BUS_PROPERTY("StartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
832 SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_limit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
833 SD_BUS_PROPERTY("StartLimitAction", "s", property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
834 SD_BUS_PROPERTY("FailureAction", "s", property_get_emergency_action, offsetof(Unit, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
835 SD_BUS_PROPERTY("FailureActionExitStatus", "i", bus_property_get_int, offsetof(Unit, failure_action_exit_status), SD_BUS_VTABLE_PROPERTY_CONST),
836 SD_BUS_PROPERTY("SuccessAction", "s", property_get_emergency_action, offsetof(Unit, success_action), SD_BUS_VTABLE_PROPERTY_CONST),
837 SD_BUS_PROPERTY("SuccessActionExitStatus", "i", bus_property_get_int, offsetof(Unit, success_action_exit_status), SD_BUS_VTABLE_PROPERTY_CONST),
838 SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
839 SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
840 SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), SD_BUS_VTABLE_PROPERTY_CONST),
841 SD_BUS_PROPERTY("Refs", "as", property_get_refs, 0, 0),
842
843 SD_BUS_METHOD("Start", "s", "o", method_start, SD_BUS_VTABLE_UNPRIVILEGED),
844 SD_BUS_METHOD("Stop", "s", "o", method_stop, SD_BUS_VTABLE_UNPRIVILEGED),
845 SD_BUS_METHOD("Reload", "s", "o", method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
846 SD_BUS_METHOD("Restart", "s", "o", method_restart, SD_BUS_VTABLE_UNPRIVILEGED),
847 SD_BUS_METHOD("TryRestart", "s", "o", method_try_restart, SD_BUS_VTABLE_UNPRIVILEGED),
848 SD_BUS_METHOD("ReloadOrRestart", "s", "o", method_reload_or_restart, SD_BUS_VTABLE_UNPRIVILEGED),
849 SD_BUS_METHOD("ReloadOrTryRestart", "s", "o", method_reload_or_try_restart, SD_BUS_VTABLE_UNPRIVILEGED),
850 SD_BUS_METHOD("EnqueueJob", "ss", "uososa(uosos)", bus_unit_method_enqueue_job, SD_BUS_VTABLE_UNPRIVILEGED),
851 SD_BUS_METHOD("Kill", "si", NULL, bus_unit_method_kill, SD_BUS_VTABLE_UNPRIVILEGED),
852 SD_BUS_METHOD("ResetFailed", NULL, NULL, bus_unit_method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
853 SD_BUS_METHOD("SetProperties", "ba(sv)", NULL, bus_unit_method_set_properties, SD_BUS_VTABLE_UNPRIVILEGED),
854 SD_BUS_METHOD("Ref", NULL, NULL, bus_unit_method_ref, SD_BUS_VTABLE_UNPRIVILEGED),
855 SD_BUS_METHOD("Unref", NULL, NULL, bus_unit_method_unref, SD_BUS_VTABLE_UNPRIVILEGED),
856 SD_BUS_METHOD("Clean", "as", NULL, bus_unit_method_clean, SD_BUS_VTABLE_UNPRIVILEGED),
857
858 /* For dependency types we don't support anymore always return an empty array */
859 SD_BUS_PROPERTY("RequiresOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
860 SD_BUS_PROPERTY("RequisiteOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
861 SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
862 SD_BUS_PROPERTY("RequisiteOfOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
863 /* Obsolete alias names */
864 SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
865 SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_limit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
866 SD_BUS_VTABLE_END
867 };
868
869 static int property_get_slice(
870 sd_bus *bus,
871 const char *path,
872 const char *interface,
873 const char *property,
874 sd_bus_message *reply,
875 void *userdata,
876 sd_bus_error *error) {
877
878 Unit *u = userdata;
879
880 assert(bus);
881 assert(reply);
882 assert(u);
883
884 return sd_bus_message_append(reply, "s", unit_slice_name(u));
885 }
886
887 static int property_get_current_memory(
888 sd_bus *bus,
889 const char *path,
890 const char *interface,
891 const char *property,
892 sd_bus_message *reply,
893 void *userdata,
894 sd_bus_error *error) {
895
896 uint64_t sz = (uint64_t) -1;
897 Unit *u = userdata;
898 int r;
899
900 assert(bus);
901 assert(reply);
902 assert(u);
903
904 r = unit_get_memory_current(u, &sz);
905 if (r < 0 && r != -ENODATA)
906 log_unit_warning_errno(u, r, "Failed to get memory.usage_in_bytes attribute: %m");
907
908 return sd_bus_message_append(reply, "t", sz);
909 }
910
911 static int property_get_current_tasks(
912 sd_bus *bus,
913 const char *path,
914 const char *interface,
915 const char *property,
916 sd_bus_message *reply,
917 void *userdata,
918 sd_bus_error *error) {
919
920 uint64_t cn = (uint64_t) -1;
921 Unit *u = userdata;
922 int r;
923
924 assert(bus);
925 assert(reply);
926 assert(u);
927
928 r = unit_get_tasks_current(u, &cn);
929 if (r < 0 && r != -ENODATA)
930 log_unit_warning_errno(u, r, "Failed to get pids.current attribute: %m");
931
932 return sd_bus_message_append(reply, "t", cn);
933 }
934
935 static int property_get_cpu_usage(
936 sd_bus *bus,
937 const char *path,
938 const char *interface,
939 const char *property,
940 sd_bus_message *reply,
941 void *userdata,
942 sd_bus_error *error) {
943
944 nsec_t ns = (nsec_t) -1;
945 Unit *u = userdata;
946 int r;
947
948 assert(bus);
949 assert(reply);
950 assert(u);
951
952 r = unit_get_cpu_usage(u, &ns);
953 if (r < 0 && r != -ENODATA)
954 log_unit_warning_errno(u, r, "Failed to get cpuacct.usage attribute: %m");
955
956 return sd_bus_message_append(reply, "t", ns);
957 }
958
959 static int property_get_cgroup(
960 sd_bus *bus,
961 const char *path,
962 const char *interface,
963 const char *property,
964 sd_bus_message *reply,
965 void *userdata,
966 sd_bus_error *error) {
967
968 Unit *u = userdata;
969 const char *t = NULL;
970
971 assert(bus);
972 assert(reply);
973 assert(u);
974
975 /* Three cases: a) u->cgroup_path is NULL, in which case the
976 * unit has no control group, which we report as the empty
977 * string. b) u->cgroup_path is the empty string, which
978 * indicates the root cgroup, which we report as "/". c) all
979 * other cases we report as-is. */
980
981 if (u->cgroup_path)
982 t = empty_to_root(u->cgroup_path);
983
984 return sd_bus_message_append(reply, "s", t);
985 }
986
987 static int append_process(sd_bus_message *reply, const char *p, pid_t pid, Set *pids) {
988 _cleanup_free_ char *buf = NULL, *cmdline = NULL;
989 int r;
990
991 assert(reply);
992 assert(pid > 0);
993
994 r = set_put(pids, PID_TO_PTR(pid));
995 if (IN_SET(r, 0, -EEXIST))
996 return 0;
997 if (r < 0)
998 return r;
999
1000 if (!p) {
1001 r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &buf);
1002 if (r == -ESRCH)
1003 return 0;
1004 if (r < 0)
1005 return r;
1006
1007 p = buf;
1008 }
1009
1010 (void) get_process_cmdline(pid, SIZE_MAX, PROCESS_CMDLINE_COMM_FALLBACK, &cmdline);
1011
1012 return sd_bus_message_append(reply,
1013 "(sus)",
1014 p,
1015 (uint32_t) pid,
1016 cmdline);
1017 }
1018
1019 static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) {
1020 _cleanup_closedir_ DIR *d = NULL;
1021 _cleanup_fclose_ FILE *f = NULL;
1022 int r;
1023
1024 assert(reply);
1025 assert(p);
1026
1027 r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, p, &f);
1028 if (r == -ENOENT)
1029 return 0;
1030 if (r < 0)
1031 return r;
1032
1033 for (;;) {
1034 pid_t pid;
1035
1036 r = cg_read_pid(f, &pid);
1037 if (r < 0)
1038 return r;
1039 if (r == 0)
1040 break;
1041
1042 if (is_kernel_thread(pid) > 0)
1043 continue;
1044
1045 r = append_process(reply, p, pid, pids);
1046 if (r < 0)
1047 return r;
1048 }
1049
1050 r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, p, &d);
1051 if (r == -ENOENT)
1052 return 0;
1053 if (r < 0)
1054 return r;
1055
1056 for (;;) {
1057 _cleanup_free_ char *g = NULL, *j = NULL;
1058
1059 r = cg_read_subgroup(d, &g);
1060 if (r < 0)
1061 return r;
1062 if (r == 0)
1063 break;
1064
1065 j = path_join(empty_to_root(p), g);
1066 if (!j)
1067 return -ENOMEM;
1068
1069 r = append_cgroup(reply, j, pids);
1070 if (r < 0)
1071 return r;
1072 }
1073
1074 return 0;
1075 }
1076
1077 int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1078 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1079 _cleanup_set_free_ Set *pids = NULL;
1080 Unit *u = userdata;
1081 pid_t pid;
1082 int r;
1083
1084 assert(message);
1085
1086 r = mac_selinux_unit_access_check(u, message, "status", error);
1087 if (r < 0)
1088 return r;
1089
1090 pids = set_new(NULL);
1091 if (!pids)
1092 return -ENOMEM;
1093
1094 r = sd_bus_message_new_method_return(message, &reply);
1095 if (r < 0)
1096 return r;
1097
1098 r = sd_bus_message_open_container(reply, 'a', "(sus)");
1099 if (r < 0)
1100 return r;
1101
1102 if (u->cgroup_path) {
1103 r = append_cgroup(reply, u->cgroup_path, pids);
1104 if (r < 0)
1105 return r;
1106 }
1107
1108 /* The main and control pids might live outside of the cgroup, hence fetch them separately */
1109 pid = unit_main_pid(u);
1110 if (pid > 0) {
1111 r = append_process(reply, NULL, pid, pids);
1112 if (r < 0)
1113 return r;
1114 }
1115
1116 pid = unit_control_pid(u);
1117 if (pid > 0) {
1118 r = append_process(reply, NULL, pid, pids);
1119 if (r < 0)
1120 return r;
1121 }
1122
1123 r = sd_bus_message_close_container(reply);
1124 if (r < 0)
1125 return r;
1126
1127 return sd_bus_send(NULL, reply, NULL);
1128 }
1129
1130 static int property_get_ip_counter(
1131 sd_bus *bus,
1132 const char *path,
1133 const char *interface,
1134 const char *property,
1135 sd_bus_message *reply,
1136 void *userdata,
1137 sd_bus_error *error) {
1138
1139 static const char *const table[_CGROUP_IP_ACCOUNTING_METRIC_MAX] = {
1140 [CGROUP_IP_INGRESS_BYTES] = "IPIngressBytes",
1141 [CGROUP_IP_EGRESS_BYTES] = "IPEgressBytes",
1142 [CGROUP_IP_INGRESS_PACKETS] = "IPIngressPackets",
1143 [CGROUP_IP_EGRESS_PACKETS] = "IPEgressPackets",
1144 };
1145
1146 uint64_t value = UINT64_MAX;
1147 Unit *u = userdata;
1148 ssize_t metric;
1149
1150 assert(bus);
1151 assert(reply);
1152 assert(property);
1153 assert(u);
1154
1155 assert_se((metric = string_table_lookup(table, ELEMENTSOF(table), property)) >= 0);
1156 (void) unit_get_ip_accounting(u, metric, &value);
1157 return sd_bus_message_append(reply, "t", value);
1158 }
1159
1160 static int property_get_io_counter(
1161 sd_bus *bus,
1162 const char *path,
1163 const char *interface,
1164 const char *property,
1165 sd_bus_message *reply,
1166 void *userdata,
1167 sd_bus_error *error) {
1168
1169 static const char *const table[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
1170 [CGROUP_IO_READ_BYTES] = "IOReadBytes",
1171 [CGROUP_IO_WRITE_BYTES] = "IOWriteBytes",
1172 [CGROUP_IO_READ_OPERATIONS] = "IOReadOperations",
1173 [CGROUP_IO_WRITE_OPERATIONS] = "IOWriteOperations",
1174 };
1175
1176 uint64_t value = UINT64_MAX;
1177 Unit *u = userdata;
1178 ssize_t metric;
1179
1180 assert(bus);
1181 assert(reply);
1182 assert(property);
1183 assert(u);
1184
1185 assert_se((metric = string_table_lookup(table, ELEMENTSOF(table), property)) >= 0);
1186 (void) unit_get_io_accounting(u, metric, false, &value);
1187 return sd_bus_message_append(reply, "t", value);
1188 }
1189
1190 int bus_unit_method_attach_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1191
1192 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1193 _cleanup_set_free_ Set *pids = NULL;
1194 Unit *u = userdata;
1195 const char *path;
1196 int r;
1197
1198 assert(message);
1199
1200 /* This migrates the processes with the specified PIDs into the cgroup of this unit, optionally below a
1201 * specified cgroup path. Obviously this only works for units that actually maintain a cgroup
1202 * representation. If a process is already in the cgroup no operation is executed – in this case the specified
1203 * subcgroup path has no effect! */
1204
1205 r = mac_selinux_unit_access_check(u, message, "start", error);
1206 if (r < 0)
1207 return r;
1208
1209 r = sd_bus_message_read(message, "s", &path);
1210 if (r < 0)
1211 return r;
1212
1213 path = empty_to_null(path);
1214 if (path) {
1215 if (!path_is_absolute(path))
1216 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Control group path is not absolute: %s", path);
1217
1218 if (!path_is_normalized(path))
1219 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Control group path is not normalized: %s", path);
1220 }
1221
1222 if (!unit_cgroup_delegate(u))
1223 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Process migration not available on non-delegated units.");
1224
1225 if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)))
1226 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit is not active, refusing.");
1227
1228 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
1229 if (r < 0)
1230 return r;
1231
1232 r = sd_bus_message_enter_container(message, 'a', "u");
1233 if (r < 0)
1234 return r;
1235 for (;;) {
1236 uid_t process_uid, sender_uid;
1237 uint32_t upid;
1238 pid_t pid;
1239
1240 r = sd_bus_message_read(message, "u", &upid);
1241 if (r < 0)
1242 return r;
1243 if (r == 0)
1244 break;
1245
1246 if (upid == 0) {
1247 r = sd_bus_creds_get_pid(creds, &pid);
1248 if (r < 0)
1249 return r;
1250 } else
1251 pid = (uid_t) upid;
1252
1253 /* Filter out duplicates */
1254 if (set_contains(pids, PID_TO_PTR(pid)))
1255 continue;
1256
1257 /* Check if this process is suitable for attaching to this unit */
1258 r = unit_pid_attachable(u, pid, error);
1259 if (r < 0)
1260 return r;
1261
1262 /* Let's query the sender's UID, so that we can make our security decisions */
1263 r = sd_bus_creds_get_euid(creds, &sender_uid);
1264 if (r < 0)
1265 return r;
1266
1267 /* Let's validate security: if the sender is root, then all is OK. If the sender is any other unit,
1268 * then the process' UID and the target unit's UID have to match the sender's UID */
1269 if (sender_uid != 0 && sender_uid != getuid()) {
1270 r = get_process_uid(pid, &process_uid);
1271 if (r < 0)
1272 return sd_bus_error_set_errnof(error, r, "Failed to retrieve process UID: %m");
1273
1274 if (process_uid != sender_uid)
1275 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by client's UID. Refusing.", pid);
1276 if (process_uid != u->ref_uid)
1277 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by target unit's UID. Refusing.", pid);
1278 }
1279
1280 if (!pids) {
1281 pids = set_new(NULL);
1282 if (!pids)
1283 return -ENOMEM;
1284 }
1285
1286 r = set_put(pids, PID_TO_PTR(pid));
1287 if (r < 0)
1288 return r;
1289 }
1290
1291 r = sd_bus_message_exit_container(message);
1292 if (r < 0)
1293 return r;
1294
1295 r = unit_attach_pids_to_cgroup(u, pids, path);
1296 if (r < 0)
1297 return sd_bus_error_set_errnof(error, r, "Failed to attach processes to control group: %m");
1298
1299 return sd_bus_reply_method_return(message, NULL);
1300 }
1301
1302 const sd_bus_vtable bus_unit_cgroup_vtable[] = {
1303 SD_BUS_VTABLE_START(0),
1304 SD_BUS_PROPERTY("Slice", "s", property_get_slice, 0, 0),
1305 SD_BUS_PROPERTY("ControlGroup", "s", property_get_cgroup, 0, 0),
1306 SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
1307 SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
1308 SD_BUS_PROPERTY("TasksCurrent", "t", property_get_current_tasks, 0, 0),
1309 SD_BUS_PROPERTY("IPIngressBytes", "t", property_get_ip_counter, 0, 0),
1310 SD_BUS_PROPERTY("IPIngressPackets", "t", property_get_ip_counter, 0, 0),
1311 SD_BUS_PROPERTY("IPEgressBytes", "t", property_get_ip_counter, 0, 0),
1312 SD_BUS_PROPERTY("IPEgressPackets", "t", property_get_ip_counter, 0, 0),
1313 SD_BUS_PROPERTY("IOReadBytes", "t", property_get_io_counter, 0, 0),
1314 SD_BUS_PROPERTY("IOReadOperations", "t", property_get_io_counter, 0, 0),
1315 SD_BUS_PROPERTY("IOWriteBytes", "t", property_get_io_counter, 0, 0),
1316 SD_BUS_PROPERTY("IOWriteOperations", "t", property_get_io_counter, 0, 0),
1317 SD_BUS_METHOD("GetProcesses", NULL, "a(sus)", bus_unit_method_get_processes, SD_BUS_VTABLE_UNPRIVILEGED),
1318 SD_BUS_METHOD("AttachProcesses", "sau", NULL, bus_unit_method_attach_processes, SD_BUS_VTABLE_UNPRIVILEGED),
1319 SD_BUS_VTABLE_END
1320 };
1321
1322 static int send_new_signal(sd_bus *bus, void *userdata) {
1323 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
1324 _cleanup_free_ char *p = NULL;
1325 Unit *u = userdata;
1326 int r;
1327
1328 assert(bus);
1329 assert(u);
1330
1331 p = unit_dbus_path(u);
1332 if (!p)
1333 return -ENOMEM;
1334
1335 r = sd_bus_message_new_signal(
1336 bus,
1337 &m,
1338 "/org/freedesktop/systemd1",
1339 "org.freedesktop.systemd1.Manager",
1340 "UnitNew");
1341 if (r < 0)
1342 return r;
1343
1344 r = sd_bus_message_append(m, "so", u->id, p);
1345 if (r < 0)
1346 return r;
1347
1348 return sd_bus_send(bus, m, NULL);
1349 }
1350
1351 static int send_changed_signal(sd_bus *bus, void *userdata) {
1352 _cleanup_free_ char *p = NULL;
1353 Unit *u = userdata;
1354 int r;
1355
1356 assert(bus);
1357 assert(u);
1358
1359 p = unit_dbus_path(u);
1360 if (!p)
1361 return -ENOMEM;
1362
1363 /* Send a properties changed signal. First for the specific
1364 * type, then for the generic unit. The clients may rely on
1365 * this order to get atomic behavior if needed. */
1366
1367 r = sd_bus_emit_properties_changed_strv(
1368 bus, p,
1369 unit_dbus_interface_from_type(u->type),
1370 NULL);
1371 if (r < 0)
1372 return r;
1373
1374 return sd_bus_emit_properties_changed_strv(
1375 bus, p,
1376 "org.freedesktop.systemd1.Unit",
1377 NULL);
1378 }
1379
1380 void bus_unit_send_change_signal(Unit *u) {
1381 int r;
1382 assert(u);
1383
1384 if (u->in_dbus_queue) {
1385 LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
1386 u->in_dbus_queue = false;
1387 }
1388
1389 if (!u->id)
1390 return;
1391
1392 r = bus_foreach_bus(u->manager, u->bus_track, u->sent_dbus_new_signal ? send_changed_signal : send_new_signal, u);
1393 if (r < 0)
1394 log_unit_debug_errno(u, r, "Failed to send unit change signal for %s: %m", u->id);
1395
1396 u->sent_dbus_new_signal = true;
1397 }
1398
1399 void bus_unit_send_pending_change_signal(Unit *u, bool including_new) {
1400
1401 /* Sends out any pending change signals, but only if they really are pending. This call is used when we are
1402 * about to change state in order to force out a PropertiesChanged signal beforehand if there was one pending
1403 * so that clients can follow the full state transition */
1404
1405 if (!u->in_dbus_queue) /* If not enqueued, don't bother */
1406 return;
1407
1408 if (!u->sent_dbus_new_signal && !including_new) /* If the unit was never announced, don't bother, it's fine if
1409 * the unit appears in the new state right-away (except if the
1410 * caller explicitly asked us to send it anyway) */
1411 return;
1412
1413 if (MANAGER_IS_RELOADING(u->manager)) /* Don't generate unnecessary PropertiesChanged signals for the same unit
1414 * when we are reloading. */
1415 return;
1416
1417 bus_unit_send_change_signal(u);
1418 }
1419
1420 static int send_removed_signal(sd_bus *bus, void *userdata) {
1421 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
1422 _cleanup_free_ char *p = NULL;
1423 Unit *u = userdata;
1424 int r;
1425
1426 assert(bus);
1427 assert(u);
1428
1429 p = unit_dbus_path(u);
1430 if (!p)
1431 return -ENOMEM;
1432
1433 r = sd_bus_message_new_signal(
1434 bus,
1435 &m,
1436 "/org/freedesktop/systemd1",
1437 "org.freedesktop.systemd1.Manager",
1438 "UnitRemoved");
1439 if (r < 0)
1440 return r;
1441
1442 r = sd_bus_message_append(m, "so", u->id, p);
1443 if (r < 0)
1444 return r;
1445
1446 return sd_bus_send(bus, m, NULL);
1447 }
1448
1449 void bus_unit_send_removed_signal(Unit *u) {
1450 int r;
1451 assert(u);
1452
1453 if (!u->sent_dbus_new_signal || u->in_dbus_queue)
1454 bus_unit_send_change_signal(u);
1455
1456 if (!u->id)
1457 return;
1458
1459 r = bus_foreach_bus(u->manager, u->bus_track, send_removed_signal, u);
1460 if (r < 0)
1461 log_unit_debug_errno(u, r, "Failed to send unit remove signal for %s: %m", u->id);
1462 }
1463
1464 int bus_unit_queue_job(
1465 sd_bus_message *message,
1466 Unit *u,
1467 JobType type,
1468 JobMode mode,
1469 BusUnitQueueFlags flags,
1470 sd_bus_error *error) {
1471
1472 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1473 _cleanup_free_ char *job_path = NULL, *unit_path = NULL;
1474 _cleanup_(set_freep) Set *affected = NULL;
1475 Iterator i;
1476 Job *j, *a;
1477 int r;
1478
1479 assert(message);
1480 assert(u);
1481 assert(type >= 0 && type < _JOB_TYPE_MAX);
1482 assert(mode >= 0 && mode < _JOB_MODE_MAX);
1483
1484 r = mac_selinux_unit_access_check(
1485 u, message,
1486 job_type_to_access_method(type),
1487 error);
1488 if (r < 0)
1489 return r;
1490
1491 if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE) && unit_can_reload(u)) {
1492 if (type == JOB_RESTART)
1493 type = JOB_RELOAD_OR_START;
1494 else if (type == JOB_TRY_RESTART)
1495 type = JOB_TRY_RELOAD;
1496 }
1497
1498 if (type == JOB_STOP &&
1499 IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_ERROR, UNIT_BAD_SETTING) &&
1500 unit_active_state(u) == UNIT_INACTIVE)
1501 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
1502
1503 if ((type == JOB_START && u->refuse_manual_start) ||
1504 (type == JOB_STOP && u->refuse_manual_stop) ||
1505 (IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
1506 (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
1507 return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
1508
1509 if (FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) {
1510 affected = set_new(NULL);
1511 if (!affected)
1512 return -ENOMEM;
1513 }
1514
1515 r = manager_add_job(u->manager, type, u, mode, affected, error, &j);
1516 if (r < 0)
1517 return r;
1518
1519 r = bus_job_track_sender(j, message);
1520 if (r < 0)
1521 return r;
1522
1523 /* Before we send the method reply, force out the announcement JobNew for this job */
1524 bus_job_send_pending_change_signal(j, true);
1525
1526 job_path = job_dbus_path(j);
1527 if (!job_path)
1528 return -ENOMEM;
1529
1530 /* The classic response is just a job object path */
1531 if (!FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY))
1532 return sd_bus_reply_method_return(message, "o", job_path);
1533
1534 /* In verbose mode respond with the anchor job plus everything that has been affected */
1535 r = sd_bus_message_new_method_return(message, &reply);
1536 if (r < 0)
1537 return r;
1538
1539 unit_path = unit_dbus_path(j->unit);
1540 if (!unit_path)
1541 return -ENOMEM;
1542
1543 r = sd_bus_message_append(reply, "uosos",
1544 j->id, job_path,
1545 j->unit->id, unit_path,
1546 job_type_to_string(j->type));
1547 if (r < 0)
1548 return r;
1549
1550 r = sd_bus_message_open_container(reply, 'a', "(uosos)");
1551 if (r < 0)
1552 return r;
1553
1554 SET_FOREACH(a, affected, i) {
1555
1556 if (a->id == j->id)
1557 continue;
1558
1559 /* Free paths from previous iteration */
1560 job_path = mfree(job_path);
1561 unit_path = mfree(unit_path);
1562
1563 job_path = job_dbus_path(a);
1564 if (!job_path)
1565 return -ENOMEM;
1566
1567 unit_path = unit_dbus_path(a->unit);
1568 if (!unit_path)
1569 return -ENOMEM;
1570
1571 r = sd_bus_message_append(reply, "(uosos)",
1572 a->id, job_path,
1573 a->unit->id, unit_path,
1574 job_type_to_string(a->type));
1575 if (r < 0)
1576 return r;
1577 }
1578
1579 r = sd_bus_message_close_container(reply);
1580 if (r < 0)
1581 return r;
1582
1583 return sd_bus_send(NULL, reply, NULL);
1584 }
1585
1586 static int bus_unit_set_live_property(
1587 Unit *u,
1588 const char *name,
1589 sd_bus_message *message,
1590 UnitWriteFlags flags,
1591 sd_bus_error *error) {
1592
1593 int r;
1594
1595 assert(u);
1596 assert(name);
1597 assert(message);
1598
1599 /* Handles setting properties both "live" (i.e. at any time during runtime), and during creation (for transient
1600 * units that are being created). */
1601
1602 if (streq(name, "Description")) {
1603 const char *d;
1604
1605 r = sd_bus_message_read(message, "s", &d);
1606 if (r < 0)
1607 return r;
1608
1609 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1610 r = unit_set_description(u, d);
1611 if (r < 0)
1612 return r;
1613
1614 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Description=%s", d);
1615 }
1616
1617 return 1;
1618 }
1619
1620 return 0;
1621 }
1622
1623 static int bus_set_transient_emergency_action(
1624 Unit *u,
1625 const char *name,
1626 EmergencyAction *p,
1627 sd_bus_message *message,
1628 UnitWriteFlags flags,
1629 sd_bus_error *error) {
1630
1631 const char *s;
1632 EmergencyAction v;
1633 int r;
1634 bool system;
1635
1636 assert(p);
1637
1638 r = sd_bus_message_read(message, "s", &s);
1639 if (r < 0)
1640 return r;
1641
1642 system = MANAGER_IS_SYSTEM(u->manager);
1643 r = parse_emergency_action(s, system, &v);
1644 if (r < 0)
1645 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
1646 r == -EOPNOTSUPP ? "%s setting invalid for manager type: %s"
1647 : "Invalid %s setting: %s",
1648 name, s);
1649
1650 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1651 *p = v;
1652 unit_write_settingf(u, flags, name,
1653 "%s=%s", name, s);
1654 }
1655
1656 return 1;
1657 }
1658
1659 static int bus_set_transient_exit_status(
1660 Unit *u,
1661 const char *name,
1662 int *p,
1663 sd_bus_message *message,
1664 UnitWriteFlags flags,
1665 sd_bus_error *error) {
1666
1667 int32_t k;
1668 int r;
1669
1670 assert(p);
1671
1672 r = sd_bus_message_read(message, "i", &k);
1673 if (r < 0)
1674 return r;
1675
1676 if (k > 255)
1677 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Exit status must be in range 0…255 or negative.");
1678
1679 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1680 *p = k < 0 ? -1 : k;
1681
1682 if (k < 0)
1683 unit_write_settingf(u, flags, name, "%s=", name);
1684 else
1685 unit_write_settingf(u, flags, name, "%s=%i", name, k);
1686 }
1687
1688 return 1;
1689 }
1690
1691 static BUS_DEFINE_SET_TRANSIENT_PARSE(collect_mode, CollectMode, collect_mode_from_string);
1692 static BUS_DEFINE_SET_TRANSIENT_PARSE(job_mode, JobMode, job_mode_from_string);
1693
1694 static int bus_set_transient_conditions(
1695 Unit *u,
1696 const char *name,
1697 Condition **list,
1698 bool is_condition,
1699 sd_bus_message *message,
1700 UnitWriteFlags flags,
1701 sd_bus_error *error) {
1702
1703 const char *type_name, *param;
1704 int trigger, negate, r;
1705 bool empty = true;
1706
1707 assert(list);
1708
1709 r = sd_bus_message_enter_container(message, 'a', "(sbbs)");
1710 if (r < 0)
1711 return r;
1712
1713 while ((r = sd_bus_message_read(message, "(sbbs)", &type_name, &trigger, &negate, &param)) > 0) {
1714 ConditionType t;
1715
1716 t = is_condition ? condition_type_from_string(type_name) : assert_type_from_string(type_name);
1717 if (t < 0)
1718 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid condition type: %s", type_name);
1719
1720 if (t != CONDITION_NULL) {
1721 if (isempty(param))
1722 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Condition parameter in %s is empty", type_name);
1723
1724 if (condition_takes_path(t) && !path_is_absolute(param))
1725 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in condition %s is not absolute: %s", type_name, param);
1726 } else
1727 param = NULL;
1728
1729 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1730 Condition *c;
1731
1732 c = condition_new(t, param, trigger, negate);
1733 if (!c)
1734 return -ENOMEM;
1735
1736 LIST_PREPEND(conditions, *list, c);
1737
1738 if (t != CONDITION_NULL)
1739 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
1740 "%s=%s%s%s", type_name,
1741 trigger ? "|" : "", negate ? "!" : "", param);
1742 else
1743 unit_write_settingf(u, flags, name,
1744 "%s=%s%s", type_name,
1745 trigger ? "|" : "", yes_no(!negate));
1746 }
1747
1748 empty = false;
1749 }
1750 if (r < 0)
1751 return r;
1752
1753 r = sd_bus_message_exit_container(message);
1754 if (r < 0)
1755 return r;
1756
1757 if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
1758 *list = condition_free_list(*list);
1759 unit_write_settingf(u, flags, name, "%sNull=", is_condition ? "Condition" : "Assert");
1760 }
1761
1762 return 1;
1763 }
1764
1765 static int bus_unit_set_transient_property(
1766 Unit *u,
1767 const char *name,
1768 sd_bus_message *message,
1769 UnitWriteFlags flags,
1770 sd_bus_error *error) {
1771
1772 UnitDependency d = _UNIT_DEPENDENCY_INVALID;
1773 int r;
1774
1775 assert(u);
1776 assert(name);
1777 assert(message);
1778
1779 /* Handles settings when transient units are created. This settings cannot be altered anymore after the unit
1780 * has been created. */
1781
1782 if (streq(name, "SourcePath"))
1783 return bus_set_transient_path(u, name, &u->source_path, message, flags, error);
1784
1785 if (streq(name, "StopWhenUnneeded"))
1786 return bus_set_transient_bool(u, name, &u->stop_when_unneeded, message, flags, error);
1787
1788 if (streq(name, "RefuseManualStart"))
1789 return bus_set_transient_bool(u, name, &u->refuse_manual_start, message, flags, error);
1790
1791 if (streq(name, "RefuseManualStop"))
1792 return bus_set_transient_bool(u, name, &u->refuse_manual_stop, message, flags, error);
1793
1794 if (streq(name, "AllowIsolate"))
1795 return bus_set_transient_bool(u, name, &u->allow_isolate, message, flags, error);
1796
1797 if (streq(name, "DefaultDependencies"))
1798 return bus_set_transient_bool(u, name, &u->default_dependencies, message, flags, error);
1799
1800 if (streq(name, "OnFailureJobMode"))
1801 return bus_set_transient_job_mode(u, name, &u->on_failure_job_mode, message, flags, error);
1802
1803 if (streq(name, "IgnoreOnIsolate"))
1804 return bus_set_transient_bool(u, name, &u->ignore_on_isolate, message, flags, error);
1805
1806 if (streq(name, "JobTimeoutUSec")) {
1807 r = bus_set_transient_usec_fix_0(u, name, &u->job_timeout, message, flags, error);
1808 if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags) && !u->job_running_timeout_set)
1809 u->job_running_timeout = u->job_timeout;
1810 }
1811
1812 if (streq(name, "JobRunningTimeoutUSec")) {
1813 r = bus_set_transient_usec_fix_0(u, name, &u->job_running_timeout, message, flags, error);
1814 if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags))
1815 u->job_running_timeout_set = true;
1816
1817 return r;
1818 }
1819
1820 if (streq(name, "JobTimeoutAction"))
1821 return bus_set_transient_emergency_action(u, name, &u->job_timeout_action, message, flags, error);
1822
1823 if (streq(name, "JobTimeoutRebootArgument"))
1824 return bus_set_transient_string(u, name, &u->job_timeout_reboot_arg, message, flags, error);
1825
1826 if (streq(name, "StartLimitIntervalUSec"))
1827 return bus_set_transient_usec(u, name, &u->start_limit.interval, message, flags, error);
1828
1829 if (streq(name, "StartLimitBurst"))
1830 return bus_set_transient_unsigned(u, name, &u->start_limit.burst, message, flags, error);
1831
1832 if (streq(name, "StartLimitAction"))
1833 return bus_set_transient_emergency_action(u, name, &u->start_limit_action, message, flags, error);
1834
1835 if (streq(name, "FailureAction"))
1836 return bus_set_transient_emergency_action(u, name, &u->failure_action, message, flags, error);
1837
1838 if (streq(name, "SuccessAction"))
1839 return bus_set_transient_emergency_action(u, name, &u->success_action, message, flags, error);
1840
1841 if (streq(name, "FailureActionExitStatus"))
1842 return bus_set_transient_exit_status(u, name, &u->failure_action_exit_status, message, flags, error);
1843
1844 if (streq(name, "SuccessActionExitStatus"))
1845 return bus_set_transient_exit_status(u, name, &u->success_action_exit_status, message, flags, error);
1846
1847 if (streq(name, "RebootArgument"))
1848 return bus_set_transient_string(u, name, &u->reboot_arg, message, flags, error);
1849
1850 if (streq(name, "CollectMode"))
1851 return bus_set_transient_collect_mode(u, name, &u->collect_mode, message, flags, error);
1852
1853 if (streq(name, "Conditions"))
1854 return bus_set_transient_conditions(u, name, &u->conditions, true, message, flags, error);
1855
1856 if (streq(name, "Asserts"))
1857 return bus_set_transient_conditions(u, name, &u->asserts, false, message, flags, error);
1858
1859 if (streq(name, "Documentation")) {
1860 _cleanup_strv_free_ char **l = NULL;
1861 char **p;
1862
1863 r = sd_bus_message_read_strv(message, &l);
1864 if (r < 0)
1865 return r;
1866
1867 STRV_FOREACH(p, l) {
1868 if (!documentation_url_is_valid(*p))
1869 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid URL in %s: %s", name, *p);
1870 }
1871
1872 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1873 if (strv_isempty(l)) {
1874 u->documentation = strv_free(u->documentation);
1875 unit_write_settingf(u, flags, name, "%s=", name);
1876 } else {
1877 strv_extend_strv(&u->documentation, l, false);
1878
1879 STRV_FOREACH(p, l)
1880 unit_write_settingf(u, flags, name, "%s=%s", name, *p);
1881 }
1882 }
1883
1884 return 1;
1885
1886 } else if (streq(name, "Slice")) {
1887 Unit *slice;
1888 const char *s;
1889
1890 if (!UNIT_HAS_CGROUP_CONTEXT(u))
1891 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "The slice property is only available for units with control groups.");
1892 if (u->type == UNIT_SLICE)
1893 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Slice may not be set for slice units.");
1894 if (unit_has_name(u, SPECIAL_INIT_SCOPE))
1895 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set slice for init.scope");
1896
1897 r = sd_bus_message_read(message, "s", &s);
1898 if (r < 0)
1899 return r;
1900
1901 if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
1902 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name '%s'", s);
1903
1904 /* Note that we do not dispatch the load queue here yet, as we don't want our own transient unit to be
1905 * loaded while we are still setting it up. Or in other words, we use manager_load_unit_prepare()
1906 * instead of manager_load_unit() on purpose, here. */
1907 r = manager_load_unit_prepare(u->manager, s, NULL, error, &slice);
1908 if (r < 0)
1909 return r;
1910
1911 if (slice->type != UNIT_SLICE)
1912 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit name '%s' is not a slice", s);
1913
1914 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1915 r = unit_set_slice(u, slice);
1916 if (r < 0)
1917 return r;
1918
1919 unit_write_settingf(u, flags|UNIT_PRIVATE, name, "Slice=%s", s);
1920 }
1921
1922 return 1;
1923
1924 } else if (streq(name, "RequiresMountsFor")) {
1925 _cleanup_strv_free_ char **l = NULL;
1926 char **p;
1927
1928 r = sd_bus_message_read_strv(message, &l);
1929 if (r < 0)
1930 return r;
1931
1932 STRV_FOREACH(p, l) {
1933 path_simplify(*p, true);
1934
1935 if (!path_is_absolute(*p))
1936 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not absolute: %s", name, *p);
1937
1938 if (!path_is_valid(*p))
1939 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s has invalid length: %s", name, *p);
1940
1941 if (!path_is_normalized(*p))
1942 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not normalized: %s", name, *p);
1943
1944 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1945 r = unit_require_mounts_for(u, *p, UNIT_DEPENDENCY_FILE);
1946 if (r < 0)
1947 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to add required mount \"%s\": %m", *p);
1948
1949 unit_write_settingf(u, flags, name, "%s=%s", name, *p);
1950 }
1951 }
1952
1953 return 1;
1954 }
1955
1956 if (streq(name, "RequiresOverridable"))
1957 d = UNIT_REQUIRES; /* redirect for obsolete unit dependency type */
1958 else if (streq(name, "RequisiteOverridable"))
1959 d = UNIT_REQUISITE; /* same here */
1960 else
1961 d = unit_dependency_from_string(name);
1962
1963 if (d >= 0) {
1964 const char *other;
1965
1966 r = sd_bus_message_enter_container(message, 'a', "s");
1967 if (r < 0)
1968 return r;
1969
1970 while ((r = sd_bus_message_read(message, "s", &other)) > 0) {
1971 if (!unit_name_is_valid(other, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
1972 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name %s", other);
1973
1974 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1975 _cleanup_free_ char *label = NULL;
1976
1977 r = unit_add_dependency_by_name(u, d, other, true, UNIT_DEPENDENCY_FILE);
1978 if (r < 0)
1979 return r;
1980
1981 label = strjoin(name, "-", other);
1982 if (!label)
1983 return -ENOMEM;
1984
1985 unit_write_settingf(u, flags, label, "%s=%s", unit_dependency_to_string(d), other);
1986 }
1987
1988 }
1989 if (r < 0)
1990 return r;
1991
1992 r = sd_bus_message_exit_container(message);
1993 if (r < 0)
1994 return r;
1995
1996 return 1;
1997
1998 } else if (streq(name, "AddRef")) {
1999
2000 int b;
2001
2002 /* Why is this called "AddRef" rather than just "Ref", or "Reference"? There's already a "Ref()" method
2003 * on the Unit interface, and it's probably not a good idea to expose a property and a method on the
2004 * same interface (well, strictly speaking AddRef isn't exposed as full property, we just read it for
2005 * transient units, but still). And "References" and "ReferencedBy" is already used as unit reference
2006 * dependency type, hence let's not confuse things with that.
2007 *
2008 * Note that we don't actually add the reference to the bus track. We do that only after the setup of
2009 * the transient unit is complete, so that setting this property multiple times in the same transient
2010 * unit creation call doesn't count as individual references. */
2011
2012 r = sd_bus_message_read(message, "b", &b);
2013 if (r < 0)
2014 return r;
2015
2016 if (!UNIT_WRITE_FLAGS_NOOP(flags))
2017 u->bus_track_add = b;
2018
2019 return 1;
2020 }
2021
2022 return 0;
2023 }
2024
2025 int bus_unit_set_properties(
2026 Unit *u,
2027 sd_bus_message *message,
2028 UnitWriteFlags flags,
2029 bool commit,
2030 sd_bus_error *error) {
2031
2032 bool for_real = false;
2033 unsigned n = 0;
2034 int r;
2035
2036 assert(u);
2037 assert(message);
2038
2039 /* We iterate through the array twice. First run we just check
2040 * if all passed data is valid, second run actually applies
2041 * it. This is to implement transaction-like behaviour without
2042 * actually providing full transactions. */
2043
2044 r = sd_bus_message_enter_container(message, 'a', "(sv)");
2045 if (r < 0)
2046 return r;
2047
2048 for (;;) {
2049 const char *name;
2050 UnitWriteFlags f;
2051
2052 r = sd_bus_message_enter_container(message, 'r', "sv");
2053 if (r < 0)
2054 return r;
2055 if (r == 0) {
2056 if (for_real || UNIT_WRITE_FLAGS_NOOP(flags))
2057 break;
2058
2059 /* Reached EOF. Let's try again, and this time for realz... */
2060 r = sd_bus_message_rewind(message, false);
2061 if (r < 0)
2062 return r;
2063
2064 for_real = true;
2065 continue;
2066 }
2067
2068 r = sd_bus_message_read(message, "s", &name);
2069 if (r < 0)
2070 return r;
2071
2072 if (!UNIT_VTABLE(u)->bus_set_property)
2073 return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Objects of this type do not support setting properties.");
2074
2075 r = sd_bus_message_enter_container(message, 'v', NULL);
2076 if (r < 0)
2077 return r;
2078
2079 /* If not for real, then mask out the two target flags */
2080 f = for_real ? flags : (flags & ~(UNIT_RUNTIME|UNIT_PERSISTENT));
2081
2082 r = UNIT_VTABLE(u)->bus_set_property(u, name, message, f, error);
2083 if (r == 0 && u->transient && u->load_state == UNIT_STUB)
2084 r = bus_unit_set_transient_property(u, name, message, f, error);
2085 if (r == 0)
2086 r = bus_unit_set_live_property(u, name, message, f, error);
2087 if (r < 0)
2088 return r;
2089
2090 if (r == 0)
2091 return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY, "Cannot set property %s, or unknown property.", name);
2092
2093 r = sd_bus_message_exit_container(message);
2094 if (r < 0)
2095 return r;
2096
2097 r = sd_bus_message_exit_container(message);
2098 if (r < 0)
2099 return r;
2100
2101 n += for_real;
2102 }
2103
2104 r = sd_bus_message_exit_container(message);
2105 if (r < 0)
2106 return r;
2107
2108 if (commit && n > 0 && UNIT_VTABLE(u)->bus_commit_properties)
2109 UNIT_VTABLE(u)->bus_commit_properties(u);
2110
2111 return n;
2112 }
2113
2114 int bus_unit_validate_load_state(Unit *u, sd_bus_error *error) {
2115 assert(u);
2116
2117 /* Generates a pretty error if a unit isn't properly loaded. */
2118
2119 switch (u->load_state) {
2120
2121 case UNIT_LOADED:
2122 return 0;
2123
2124 case UNIT_NOT_FOUND:
2125 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not found.", u->id);
2126
2127 case UNIT_BAD_SETTING:
2128 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING, "Unit %s has a bad unit file setting.", u->id);
2129
2130 case UNIT_ERROR: /* Only show .load_error in UNIT_ERROR state */
2131 return sd_bus_error_set_errnof(error, u->load_error, "Unit %s failed to load properly: %m.", u->id);
2132
2133 case UNIT_MASKED:
2134 return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit %s is masked.", u->id);
2135
2136 case UNIT_STUB:
2137 case UNIT_MERGED:
2138 default:
2139 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unexpected load state of unit %s", u->id);
2140 }
2141 }
2142
2143 static int bus_unit_track_handler(sd_bus_track *t, void *userdata) {
2144 Unit *u = userdata;
2145
2146 assert(t);
2147 assert(u);
2148
2149 u->bus_track = sd_bus_track_unref(u->bus_track); /* make sure we aren't called again */
2150
2151 /* If the client that tracks us disappeared, then there's reason to believe that the cgroup is empty now too,
2152 * let's see */
2153 unit_add_to_cgroup_empty_queue(u);
2154
2155 /* Also add the unit to the GC queue, after all if the client left it might be time to GC this unit */
2156 unit_add_to_gc_queue(u);
2157
2158 return 0;
2159 }
2160
2161 static int bus_unit_allocate_bus_track(Unit *u) {
2162 int r;
2163
2164 assert(u);
2165
2166 if (u->bus_track)
2167 return 0;
2168
2169 r = sd_bus_track_new(u->manager->api_bus, &u->bus_track, bus_unit_track_handler, u);
2170 if (r < 0)
2171 return r;
2172
2173 r = sd_bus_track_set_recursive(u->bus_track, true);
2174 if (r < 0) {
2175 u->bus_track = sd_bus_track_unref(u->bus_track);
2176 return r;
2177 }
2178
2179 return 0;
2180 }
2181
2182 int bus_unit_track_add_name(Unit *u, const char *name) {
2183 int r;
2184
2185 assert(u);
2186
2187 r = bus_unit_allocate_bus_track(u);
2188 if (r < 0)
2189 return r;
2190
2191 return sd_bus_track_add_name(u->bus_track, name);
2192 }
2193
2194 int bus_unit_track_add_sender(Unit *u, sd_bus_message *m) {
2195 int r;
2196
2197 assert(u);
2198
2199 r = bus_unit_allocate_bus_track(u);
2200 if (r < 0)
2201 return r;
2202
2203 return sd_bus_track_add_sender(u->bus_track, m);
2204 }
2205
2206 int bus_unit_track_remove_sender(Unit *u, sd_bus_message *m) {
2207 assert(u);
2208
2209 /* If we haven't allocated the bus track object yet, then there's definitely no reference taken yet, return an
2210 * error */
2211 if (!u->bus_track)
2212 return -EUNATCH;
2213
2214 return sd_bus_track_remove_sender(u->bus_track, m);
2215 }