1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "alloc-util.h"
7 #include "bpf-firewall.h"
9 #include "cgroup-util.h"
11 #include "dbus-cgroup.h"
12 #include "dbus-util.h"
13 #include "errno-util.h"
16 #include "limits-util.h"
17 #include "path-util.h"
19 BUS_DEFINE_PROPERTY_GET(bus_property_get_tasks_max
, "t", TasksMax
, tasks_max_resolve
);
21 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy
, cgroup_device_policy
, CGroupDevicePolicy
);
23 static int property_get_cgroup_mask(
26 const char *interface
,
28 sd_bus_message
*reply
,
30 sd_bus_error
*error
) {
32 CGroupMask
*mask
= userdata
;
33 CGroupController ctrl
;
39 r
= sd_bus_message_open_container(reply
, 'a', "s");
43 for (ctrl
= 0; ctrl
< _CGROUP_CONTROLLER_MAX
; ctrl
++) {
44 if ((*mask
& CGROUP_CONTROLLER_TO_MASK(ctrl
)) == 0)
47 r
= sd_bus_message_append(reply
, "s", cgroup_controller_to_string(ctrl
));
52 return sd_bus_message_close_container(reply
);
55 static int property_get_delegate_controllers(
58 const char *interface
,
60 sd_bus_message
*reply
,
62 sd_bus_error
*error
) {
64 CGroupContext
*c
= userdata
;
71 return sd_bus_message_append(reply
, "as", 0);
73 return property_get_cgroup_mask(bus
, path
, interface
, property
, reply
, &c
->delegate_controllers
, error
);
76 static int property_get_cpuset(
79 const char *interface
,
81 sd_bus_message
*reply
,
83 sd_bus_error
*error
) {
85 CPUSet
*cpus
= userdata
;
86 _cleanup_free_
uint8_t *array
= NULL
;
93 (void) cpu_set_to_dbus(cpus
, &array
, &allocated
);
94 return sd_bus_message_append_array(reply
, 'y', array
, allocated
);
97 static int property_get_io_device_weight(
100 const char *interface
,
101 const char *property
,
102 sd_bus_message
*reply
,
104 sd_bus_error
*error
) {
106 CGroupContext
*c
= userdata
;
107 CGroupIODeviceWeight
*w
;
114 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
118 LIST_FOREACH(device_weights
, w
, c
->io_device_weights
) {
119 r
= sd_bus_message_append(reply
, "(st)", w
->path
, w
->weight
);
124 return sd_bus_message_close_container(reply
);
127 static int property_get_io_device_limits(
130 const char *interface
,
131 const char *property
,
132 sd_bus_message
*reply
,
134 sd_bus_error
*error
) {
136 CGroupContext
*c
= userdata
;
137 CGroupIODeviceLimit
*l
;
144 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
148 LIST_FOREACH(device_limits
, l
, c
->io_device_limits
) {
149 CGroupIOLimitType type
;
151 type
= cgroup_io_limit_type_from_string(property
);
152 if (type
< 0 || l
->limits
[type
] == cgroup_io_limit_defaults
[type
])
155 r
= sd_bus_message_append(reply
, "(st)", l
->path
, l
->limits
[type
]);
160 return sd_bus_message_close_container(reply
);
163 static int property_get_io_device_latency(
166 const char *interface
,
167 const char *property
,
168 sd_bus_message
*reply
,
170 sd_bus_error
*error
) {
172 CGroupContext
*c
= userdata
;
173 CGroupIODeviceLatency
*l
;
180 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
184 LIST_FOREACH(device_latencies
, l
, c
->io_device_latencies
) {
185 r
= sd_bus_message_append(reply
, "(st)", l
->path
, l
->target_usec
);
190 return sd_bus_message_close_container(reply
);
193 static int property_get_blockio_device_weight(
196 const char *interface
,
197 const char *property
,
198 sd_bus_message
*reply
,
200 sd_bus_error
*error
) {
202 CGroupContext
*c
= userdata
;
203 CGroupBlockIODeviceWeight
*w
;
210 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
214 LIST_FOREACH(device_weights
, w
, c
->blockio_device_weights
) {
215 r
= sd_bus_message_append(reply
, "(st)", w
->path
, w
->weight
);
220 return sd_bus_message_close_container(reply
);
223 static int property_get_blockio_device_bandwidths(
226 const char *interface
,
227 const char *property
,
228 sd_bus_message
*reply
,
230 sd_bus_error
*error
) {
232 CGroupContext
*c
= userdata
;
233 CGroupBlockIODeviceBandwidth
*b
;
240 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
244 LIST_FOREACH(device_bandwidths
, b
, c
->blockio_device_bandwidths
) {
247 if (streq(property
, "BlockIOReadBandwidth"))
252 if (v
== CGROUP_LIMIT_MAX
)
255 r
= sd_bus_message_append(reply
, "(st)", b
->path
, v
);
260 return sd_bus_message_close_container(reply
);
263 static int property_get_device_allow(
266 const char *interface
,
267 const char *property
,
268 sd_bus_message
*reply
,
270 sd_bus_error
*error
) {
272 CGroupContext
*c
= userdata
;
273 CGroupDeviceAllow
*a
;
280 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
284 LIST_FOREACH(device_allow
, a
, c
->device_allow
) {
297 r
= sd_bus_message_append(reply
, "(ss)", a
->path
, rwm
);
302 return sd_bus_message_close_container(reply
);
305 static int property_get_ip_address_access(
308 const char *interface
,
309 const char *property
,
310 sd_bus_message
*reply
,
312 sd_bus_error
*error
) {
314 IPAddressAccessItem
** items
= userdata
, *i
;
317 r
= sd_bus_message_open_container(reply
, 'a', "(iayu)");
321 LIST_FOREACH(items
, i
, *items
) {
323 r
= sd_bus_message_open_container(reply
, 'r', "iayu");
327 r
= sd_bus_message_append(reply
, "i", i
->family
);
331 r
= sd_bus_message_append_array(reply
, 'y', &i
->address
, FAMILY_ADDRESS_SIZE(i
->family
));
335 r
= sd_bus_message_append(reply
, "u", (uint32_t) i
->prefixlen
);
339 r
= sd_bus_message_close_container(reply
);
344 return sd_bus_message_close_container(reply
);
347 const sd_bus_vtable bus_cgroup_vtable
[] = {
348 SD_BUS_VTABLE_START(0),
349 SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool
, offsetof(CGroupContext
, delegate
), 0),
350 SD_BUS_PROPERTY("DelegateControllers", "as", property_get_delegate_controllers
, 0, 0),
351 SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, cpu_accounting
), 0),
352 SD_BUS_PROPERTY("CPUWeight", "t", NULL
, offsetof(CGroupContext
, cpu_weight
), 0),
353 SD_BUS_PROPERTY("StartupCPUWeight", "t", NULL
, offsetof(CGroupContext
, startup_cpu_weight
), 0),
354 SD_BUS_PROPERTY("CPUShares", "t", NULL
, offsetof(CGroupContext
, cpu_shares
), 0),
355 SD_BUS_PROPERTY("StartupCPUShares", "t", NULL
, offsetof(CGroupContext
, startup_cpu_shares
), 0),
356 SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec
, offsetof(CGroupContext
, cpu_quota_per_sec_usec
), 0),
357 SD_BUS_PROPERTY("CPUQuotaPeriodUSec", "t", bus_property_get_usec
, offsetof(CGroupContext
, cpu_quota_period_usec
), 0),
358 SD_BUS_PROPERTY("AllowedCPUs", "ay", property_get_cpuset
, offsetof(CGroupContext
, cpuset_cpus
), 0),
359 SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset
, offsetof(CGroupContext
, cpuset_mems
), 0),
360 SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, io_accounting
), 0),
361 SD_BUS_PROPERTY("IOWeight", "t", NULL
, offsetof(CGroupContext
, io_weight
), 0),
362 SD_BUS_PROPERTY("StartupIOWeight", "t", NULL
, offsetof(CGroupContext
, startup_io_weight
), 0),
363 SD_BUS_PROPERTY("IODeviceWeight", "a(st)", property_get_io_device_weight
, 0, 0),
364 SD_BUS_PROPERTY("IOReadBandwidthMax", "a(st)", property_get_io_device_limits
, 0, 0),
365 SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits
, 0, 0),
366 SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits
, 0, 0),
367 SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits
, 0, 0),
368 SD_BUS_PROPERTY("IODeviceLatencyTargetUSec", "a(st)", property_get_io_device_latency
, 0, 0),
369 SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, blockio_accounting
), 0),
370 SD_BUS_PROPERTY("BlockIOWeight", "t", NULL
, offsetof(CGroupContext
, blockio_weight
), 0),
371 SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL
, offsetof(CGroupContext
, startup_blockio_weight
), 0),
372 SD_BUS_PROPERTY("BlockIODeviceWeight", "a(st)", property_get_blockio_device_weight
, 0, 0),
373 SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths
, 0, 0),
374 SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths
, 0, 0),
375 SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, memory_accounting
), 0),
376 SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL
, offsetof(CGroupContext
, default_memory_low
), 0),
377 SD_BUS_PROPERTY("DefaultMemoryMin", "t", NULL
, offsetof(CGroupContext
, default_memory_min
), 0),
378 SD_BUS_PROPERTY("MemoryMin", "t", NULL
, offsetof(CGroupContext
, memory_min
), 0),
379 SD_BUS_PROPERTY("MemoryLow", "t", NULL
, offsetof(CGroupContext
, memory_low
), 0),
380 SD_BUS_PROPERTY("MemoryHigh", "t", NULL
, offsetof(CGroupContext
, memory_high
), 0),
381 SD_BUS_PROPERTY("MemoryMax", "t", NULL
, offsetof(CGroupContext
, memory_max
), 0),
382 SD_BUS_PROPERTY("MemorySwapMax", "t", NULL
, offsetof(CGroupContext
, memory_swap_max
), 0),
383 SD_BUS_PROPERTY("MemoryLimit", "t", NULL
, offsetof(CGroupContext
, memory_limit
), 0),
384 SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy
, offsetof(CGroupContext
, device_policy
), 0),
385 SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow
, 0, 0),
386 SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, tasks_accounting
), 0),
387 SD_BUS_PROPERTY("TasksMax", "t", bus_property_get_tasks_max
, offsetof(CGroupContext
, tasks_max
), 0),
388 SD_BUS_PROPERTY("IPAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, ip_accounting
), 0),
389 SD_BUS_PROPERTY("IPAddressAllow", "a(iayu)", property_get_ip_address_access
, offsetof(CGroupContext
, ip_address_allow
), 0),
390 SD_BUS_PROPERTY("IPAddressDeny", "a(iayu)", property_get_ip_address_access
, offsetof(CGroupContext
, ip_address_deny
), 0),
391 SD_BUS_PROPERTY("IPIngressFilterPath", "as", NULL
, offsetof(CGroupContext
, ip_filters_ingress
), 0),
392 SD_BUS_PROPERTY("IPEgressFilterPath", "as", NULL
, offsetof(CGroupContext
, ip_filters_egress
), 0),
393 SD_BUS_PROPERTY("DisableControllers", "as", property_get_cgroup_mask
, offsetof(CGroupContext
, disable_controllers
), 0),
397 static int bus_cgroup_set_transient_property(
401 sd_bus_message
*message
,
402 UnitWriteFlags flags
,
403 sd_bus_error
*error
) {
412 flags
|= UNIT_PRIVATE
;
414 if (streq(name
, "Delegate")) {
417 if (!UNIT_VTABLE(u
)->can_delegate
)
418 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Delegation not available for unit type");
420 r
= sd_bus_message_read(message
, "b", &b
);
424 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
426 c
->delegate_controllers
= b
? _CGROUP_MASK_ALL
: 0;
428 unit_write_settingf(u
, flags
, name
, "Delegate=%s", yes_no(b
));
433 } else if (STR_IN_SET(name
, "DelegateControllers", "DisableControllers")) {
436 if (streq(name
, "DelegateControllers") && !UNIT_VTABLE(u
)->can_delegate
)
437 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Delegation not available for unit type");
439 r
= sd_bus_message_enter_container(message
, 'a', "s");
447 r
= sd_bus_message_read(message
, "s", &t
);
453 cc
= cgroup_controller_from_string(t
);
455 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown cgroup controller '%s'", t
);
457 mask
|= CGROUP_CONTROLLER_TO_MASK(cc
);
460 r
= sd_bus_message_exit_container(message
);
464 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
465 _cleanup_free_
char *t
= NULL
;
467 r
= cg_mask_to_string(mask
, &t
);
471 if (streq(name
, "DelegateControllers")) {
475 c
->delegate_controllers
= 0;
477 c
->delegate_controllers
|= mask
;
479 unit_write_settingf(u
, flags
, name
, "Delegate=%s", strempty(t
));
481 } else if (streq(name
, "DisableControllers")) {
484 c
->disable_controllers
= 0;
486 c
->disable_controllers
|= mask
;
488 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, strempty(t
));
493 } else if (STR_IN_SET(name
, "IPIngressFilterPath", "IPEgressFilterPath")) {
497 filters
= streq(name
, "IPIngressFilterPath") ? &c
->ip_filters_ingress
: &c
->ip_filters_egress
;
498 r
= sd_bus_message_enter_container(message
, 'a', "s");
505 r
= sd_bus_message_read(message
, "s", &path
);
511 if (!path_is_normalized(path
) || !path_is_absolute(path
))
512 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s= expects a normalized absolute path.", name
);
514 if (!UNIT_WRITE_FLAGS_NOOP(flags
) && !strv_contains(*filters
, path
)) {
515 r
= strv_extend(filters
, path
);
521 r
= sd_bus_message_exit_container(message
);
525 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
526 _cleanup_free_
char *buf
= NULL
;
527 _cleanup_fclose_
FILE *f
= NULL
;
532 *filters
= strv_free(*filters
);
534 unit_invalidate_cgroup_bpf(u
);
535 f
= open_memstream_unlocked(&buf
, &size
);
542 STRV_FOREACH(entry
, *filters
)
543 fprintf(f
, "%s=%s\n", name
, *entry
);
545 r
= fflush_and_check(f
);
549 unit_write_setting(u
, flags
, name
, buf
);
552 r
= bpf_firewall_supported();
555 if (r
!= BPF_FIREWALL_SUPPORTED_WITH_MULTI
) {
556 static bool warned
= false;
558 log_full(warned
? LOG_DEBUG
: LOG_WARNING
,
559 "Transient unit %s configures an IP firewall with BPF, but the local system does not support BPF/cgroup firewalling with multiple filters.\n"
560 "Starting this unit will fail! (This warning is only shown for the first started transient unit using IP firewalling.)", u
->id
);
572 static int bus_cgroup_set_boolean(
577 sd_bus_message
*message
,
578 UnitWriteFlags flags
,
579 sd_bus_error
*error
) {
585 r
= sd_bus_message_read(message
, "b", &b
);
589 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
591 unit_invalidate_cgroup(u
, mask
);
592 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, yes_no(b
));
598 #define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val) \
599 static int bus_cgroup_set_##function( \
603 sd_bus_message *message, \
604 UnitWriteFlags flags, \
605 sd_bus_error *error) { \
612 r = sd_bus_message_read(message, "t", &v); \
617 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
618 "Value specified in %s is out of range", name); \
620 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
622 unit_invalidate_cgroup(u, mask); \
625 unit_write_settingf(u, flags, name, \
628 unit_write_settingf(u, flags, name, \
629 "%s=%" PRIu64, name, v); \
635 #define BUS_DEFINE_SET_CGROUP_LIMIT(function, mask, scale, minimum) \
636 static int bus_cgroup_set_##function( \
640 sd_bus_message *message, \
641 UnitWriteFlags flags, \
642 sd_bus_error *error) { \
649 r = sd_bus_message_read(message, "t", &v); \
654 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
655 "Value specified in %s is out of range", name); \
657 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
659 unit_invalidate_cgroup(u, mask); \
661 if (v == CGROUP_LIMIT_MAX) \
662 unit_write_settingf(u, flags, name, \
663 "%s=infinity", name); \
665 unit_write_settingf(u, flags, name, \
666 "%s=%" PRIu64, name, v); \
671 static int bus_cgroup_set_##function##_scale( \
675 sd_bus_message *message, \
676 UnitWriteFlags flags, \
677 sd_bus_error *error) { \
685 r = sd_bus_message_read(message, "u", &raw); \
689 v = scale(raw, UINT32_MAX); \
690 if (v < minimum || v >= UINT64_MAX) \
691 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
692 "Value specified in %s is out of range", name); \
694 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
696 unit_invalidate_cgroup(u, mask); \
698 /* Prepare to chop off suffix */ \
699 assert_se(endswith(name, "Scale")); \
701 unit_write_settingf(u, flags, name, "%.*s=%" PRIu32 "%%", \
702 (int)(strlen(name) - strlen("Scale")), name, \
703 (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \
709 #pragma GCC diagnostic push
710 #pragma GCC diagnostic ignored "-Wtype-limits"
711 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight
, CGROUP_MASK_CPU
, CGROUP_WEIGHT_IS_OK
, CGROUP_WEIGHT_INVALID
);
712 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares
, CGROUP_MASK_CPU
, CGROUP_CPU_SHARES_IS_OK
, CGROUP_CPU_SHARES_INVALID
);
713 BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight
, CGROUP_MASK_IO
, CGROUP_WEIGHT_IS_OK
, CGROUP_WEIGHT_INVALID
);
714 BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight
, CGROUP_MASK_BLKIO
, CGROUP_BLKIO_WEIGHT_IS_OK
, CGROUP_BLKIO_WEIGHT_INVALID
);
715 BUS_DEFINE_SET_CGROUP_LIMIT(memory
, CGROUP_MASK_MEMORY
, physical_memory_scale
, 1);
716 BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection
, CGROUP_MASK_MEMORY
, physical_memory_scale
, 0);
717 BUS_DEFINE_SET_CGROUP_LIMIT(swap
, CGROUP_MASK_MEMORY
, physical_memory_scale
, 0);
718 #pragma GCC diagnostic pop
720 static int bus_cgroup_set_tasks_max(
724 sd_bus_message
*message
,
725 UnitWriteFlags flags
,
726 sd_bus_error
*error
) {
733 r
= sd_bus_message_read(message
, "t", &v
);
738 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
,
739 "Value specified in %s is out of range", name
);
741 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
742 *p
= (TasksMax
) { .value
= v
, .scale
= 0 }; /* When .scale==0, .value is the absolute value */
743 unit_invalidate_cgroup(u
, CGROUP_MASK_PIDS
);
745 if (v
== CGROUP_LIMIT_MAX
)
746 unit_write_settingf(u
, flags
, name
,
747 "%s=infinity", name
);
749 unit_write_settingf(u
, flags
, name
,
750 "%s=%" PRIu64
, name
, v
);
756 static int bus_cgroup_set_tasks_max_scale(
760 sd_bus_message
*message
,
761 UnitWriteFlags flags
,
762 sd_bus_error
*error
) {
769 r
= sd_bus_message_read(message
, "u", &v
);
773 if (v
< 1 || v
>= UINT32_MAX
)
774 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
,
775 "Value specified in %s is out of range", name
);
777 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
778 *p
= (TasksMax
) { v
, UINT32_MAX
}; /* .scale is not 0, so this is interpreted as v/UINT32_MAX. */
779 unit_invalidate_cgroup(u
, CGROUP_MASK_PIDS
);
781 unit_write_settingf(u
, flags
, name
, "%s=%" PRIu32
"%%", "TasksMax",
782 (uint32_t) (DIV_ROUND_UP((uint64_t) v
* 100U, (uint64_t) UINT32_MAX
)));
788 int bus_cgroup_set_property(
792 sd_bus_message
*message
,
793 UnitWriteFlags flags
,
794 sd_bus_error
*error
) {
796 CGroupIOLimitType iol_type
;
804 flags
|= UNIT_PRIVATE
;
806 if (streq(name
, "CPUAccounting"))
807 return bus_cgroup_set_boolean(u
, name
, &c
->cpu_accounting
, get_cpu_accounting_mask(), message
, flags
, error
);
809 if (streq(name
, "CPUWeight"))
810 return bus_cgroup_set_cpu_weight(u
, name
, &c
->cpu_weight
, message
, flags
, error
);
812 if (streq(name
, "StartupCPUWeight"))
813 return bus_cgroup_set_cpu_weight(u
, name
, &c
->startup_cpu_weight
, message
, flags
, error
);
815 if (streq(name
, "CPUShares"))
816 return bus_cgroup_set_cpu_shares(u
, name
, &c
->cpu_shares
, message
, flags
, error
);
818 if (streq(name
, "StartupCPUShares"))
819 return bus_cgroup_set_cpu_shares(u
, name
, &c
->startup_cpu_shares
, message
, flags
, error
);
821 if (streq(name
, "IOAccounting"))
822 return bus_cgroup_set_boolean(u
, name
, &c
->io_accounting
, CGROUP_MASK_IO
, message
, flags
, error
);
824 if (streq(name
, "IOWeight"))
825 return bus_cgroup_set_io_weight(u
, name
, &c
->io_weight
, message
, flags
, error
);
827 if (streq(name
, "StartupIOWeight"))
828 return bus_cgroup_set_io_weight(u
, name
, &c
->startup_io_weight
, message
, flags
, error
);
830 if (streq(name
, "BlockIOAccounting"))
831 return bus_cgroup_set_boolean(u
, name
, &c
->blockio_accounting
, CGROUP_MASK_BLKIO
, message
, flags
, error
);
833 if (streq(name
, "BlockIOWeight"))
834 return bus_cgroup_set_blockio_weight(u
, name
, &c
->blockio_weight
, message
, flags
, error
);
836 if (streq(name
, "StartupBlockIOWeight"))
837 return bus_cgroup_set_blockio_weight(u
, name
, &c
->startup_blockio_weight
, message
, flags
, error
);
839 if (streq(name
, "MemoryAccounting"))
840 return bus_cgroup_set_boolean(u
, name
, &c
->memory_accounting
, CGROUP_MASK_MEMORY
, message
, flags
, error
);
842 if (streq(name
, "MemoryMin")) {
843 r
= bus_cgroup_set_memory_protection(u
, name
, &c
->memory_min
, message
, flags
, error
);
845 c
->memory_min_set
= true;
849 if (streq(name
, "MemoryLow")) {
850 r
= bus_cgroup_set_memory_protection(u
, name
, &c
->memory_low
, message
, flags
, error
);
852 c
->memory_low_set
= true;
856 if (streq(name
, "DefaultMemoryMin")) {
857 r
= bus_cgroup_set_memory_protection(u
, name
, &c
->default_memory_min
, message
, flags
, error
);
859 c
->default_memory_min_set
= true;
863 if (streq(name
, "DefaultMemoryLow")) {
864 r
= bus_cgroup_set_memory_protection(u
, name
, &c
->default_memory_low
, message
, flags
, error
);
866 c
->default_memory_low_set
= true;
870 if (streq(name
, "MemoryHigh"))
871 return bus_cgroup_set_memory(u
, name
, &c
->memory_high
, message
, flags
, error
);
873 if (streq(name
, "MemorySwapMax"))
874 return bus_cgroup_set_swap(u
, name
, &c
->memory_swap_max
, message
, flags
, error
);
876 if (streq(name
, "MemoryMax"))
877 return bus_cgroup_set_memory(u
, name
, &c
->memory_max
, message
, flags
, error
);
879 if (streq(name
, "MemoryLimit"))
880 return bus_cgroup_set_memory(u
, name
, &c
->memory_limit
, message
, flags
, error
);
882 if (streq(name
, "MemoryMinScale")) {
883 r
= bus_cgroup_set_memory_protection_scale(u
, name
, &c
->memory_min
, message
, flags
, error
);
885 c
->memory_min_set
= true;
889 if (streq(name
, "MemoryLowScale")) {
890 r
= bus_cgroup_set_memory_protection_scale(u
, name
, &c
->memory_low
, message
, flags
, error
);
892 c
->memory_low_set
= true;
896 if (streq(name
, "DefaultMemoryMinScale")) {
897 r
= bus_cgroup_set_memory_protection_scale(u
, name
, &c
->default_memory_min
, message
, flags
, error
);
899 c
->default_memory_min_set
= true;
903 if (streq(name
, "DefaultMemoryLowScale")) {
904 r
= bus_cgroup_set_memory_protection_scale(u
, name
, &c
->default_memory_low
, message
, flags
, error
);
906 c
->default_memory_low_set
= true;
910 if (streq(name
, "MemoryHighScale"))
911 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_high
, message
, flags
, error
);
913 if (streq(name
, "MemorySwapMaxScale"))
914 return bus_cgroup_set_swap_scale(u
, name
, &c
->memory_swap_max
, message
, flags
, error
);
916 if (streq(name
, "MemoryMaxScale"))
917 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_max
, message
, flags
, error
);
919 if (streq(name
, "MemoryLimitScale"))
920 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_limit
, message
, flags
, error
);
922 if (streq(name
, "TasksAccounting"))
923 return bus_cgroup_set_boolean(u
, name
, &c
->tasks_accounting
, CGROUP_MASK_PIDS
, message
, flags
, error
);
925 if (streq(name
, "TasksMax"))
926 return bus_cgroup_set_tasks_max(u
, name
, &c
->tasks_max
, message
, flags
, error
);
928 if (streq(name
, "TasksMaxScale"))
929 return bus_cgroup_set_tasks_max_scale(u
, name
, &c
->tasks_max
, message
, flags
, error
);
931 if (streq(name
, "CPUQuotaPerSecUSec")) {
934 r
= sd_bus_message_read(message
, "t", &u64
);
939 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "CPUQuotaPerSecUSec= value out of range");
941 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
942 c
->cpu_quota_per_sec_usec
= u64
;
943 u
->warned_clamping_cpu_quota_period
= false;
944 unit_invalidate_cgroup(u
, CGROUP_MASK_CPU
);
946 if (c
->cpu_quota_per_sec_usec
== USEC_INFINITY
)
947 unit_write_setting(u
, flags
, "CPUQuota", "CPUQuota=");
949 /* config_parse_cpu_quota() requires an integer, so truncating division is used on
951 unit_write_settingf(u
, flags
, "CPUQuota",
953 (double) (c
->cpu_quota_per_sec_usec
/ 10000));
958 } else if (streq(name
, "CPUQuotaPeriodUSec")) {
961 r
= sd_bus_message_read(message
, "t", &u64
);
965 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
966 c
->cpu_quota_period_usec
= u64
;
967 u
->warned_clamping_cpu_quota_period
= false;
968 unit_invalidate_cgroup(u
, CGROUP_MASK_CPU
);
969 if (c
->cpu_quota_period_usec
== USEC_INFINITY
)
970 unit_write_setting(u
, flags
, "CPUQuotaPeriodSec", "CPUQuotaPeriodSec=");
972 char v
[FORMAT_TIMESPAN_MAX
];
973 unit_write_settingf(u
, flags
, "CPUQuotaPeriodSec",
974 "CPUQuotaPeriodSec=%s",
975 format_timespan(v
, sizeof(v
), c
->cpu_quota_period_usec
, 1));
981 } else if (STR_IN_SET(name
, "AllowedCPUs", "AllowedMemoryNodes")) {
984 _cleanup_(cpu_set_reset
) CPUSet new_set
= {};
986 r
= sd_bus_message_read_array(message
, 'y', &a
, &n
);
990 r
= cpu_set_from_dbus(a
, n
, &new_set
);
994 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
995 _cleanup_free_
char *setstr
= NULL
;
998 setstr
= cpu_set_to_range_string(&new_set
);
1002 if (streq(name
, "AllowedCPUs"))
1003 set
= &c
->cpuset_cpus
;
1005 set
= &c
->cpuset_mems
;
1009 new_set
= (CPUSet
) {};
1011 unit_invalidate_cgroup(u
, CGROUP_MASK_CPUSET
);
1012 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, setstr
);
1017 } else if ((iol_type
= cgroup_io_limit_type_from_string(name
)) >= 0) {
1022 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1026 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &u64
)) > 0) {
1028 if (!path_is_normalized(path
))
1029 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1031 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1032 CGroupIODeviceLimit
*a
= NULL
, *b
;
1034 LIST_FOREACH(device_limits
, b
, c
->io_device_limits
) {
1035 if (path_equal(path
, b
->path
)) {
1042 CGroupIOLimitType type
;
1044 a
= new0(CGroupIODeviceLimit
, 1);
1048 a
->path
= strdup(path
);
1054 for (type
= 0; type
< _CGROUP_IO_LIMIT_TYPE_MAX
; type
++)
1055 a
->limits
[type
] = cgroup_io_limit_defaults
[type
];
1057 LIST_PREPEND(device_limits
, c
->io_device_limits
, a
);
1060 a
->limits
[iol_type
] = u64
;
1068 r
= sd_bus_message_exit_container(message
);
1072 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1073 CGroupIODeviceLimit
*a
;
1074 _cleanup_free_
char *buf
= NULL
;
1075 _cleanup_fclose_
FILE *f
= NULL
;
1079 LIST_FOREACH(device_limits
, a
, c
->io_device_limits
)
1080 a
->limits
[iol_type
] = cgroup_io_limit_defaults
[iol_type
];
1083 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
1085 f
= open_memstream_unlocked(&buf
, &size
);
1089 fprintf(f
, "%s=\n", name
);
1090 LIST_FOREACH(device_limits
, a
, c
->io_device_limits
)
1091 if (a
->limits
[iol_type
] != cgroup_io_limit_defaults
[iol_type
])
1092 fprintf(f
, "%s=%s %" PRIu64
"\n", name
, a
->path
, a
->limits
[iol_type
]);
1094 r
= fflush_and_check(f
);
1097 unit_write_setting(u
, flags
, name
, buf
);
1102 } else if (streq(name
, "IODeviceWeight")) {
1107 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1111 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &weight
)) > 0) {
1113 if (!path_is_normalized(path
))
1114 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1116 if (!CGROUP_WEIGHT_IS_OK(weight
) || weight
== CGROUP_WEIGHT_INVALID
)
1117 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "IODeviceWeight= value out of range");
1119 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1120 CGroupIODeviceWeight
*a
= NULL
, *b
;
1122 LIST_FOREACH(device_weights
, b
, c
->io_device_weights
) {
1123 if (path_equal(b
->path
, path
)) {
1130 a
= new0(CGroupIODeviceWeight
, 1);
1134 a
->path
= strdup(path
);
1139 LIST_PREPEND(device_weights
, c
->io_device_weights
, a
);
1148 r
= sd_bus_message_exit_container(message
);
1152 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1153 _cleanup_free_
char *buf
= NULL
;
1154 _cleanup_fclose_
FILE *f
= NULL
;
1155 CGroupIODeviceWeight
*a
;
1159 while (c
->io_device_weights
)
1160 cgroup_context_free_io_device_weight(c
, c
->io_device_weights
);
1163 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
1165 f
= open_memstream_unlocked(&buf
, &size
);
1169 fputs("IODeviceWeight=\n", f
);
1170 LIST_FOREACH(device_weights
, a
, c
->io_device_weights
)
1171 fprintf(f
, "IODeviceWeight=%s %" PRIu64
"\n", a
->path
, a
->weight
);
1173 r
= fflush_and_check(f
);
1176 unit_write_setting(u
, flags
, name
, buf
);
1181 } else if (streq(name
, "IODeviceLatencyTargetUSec")) {
1186 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1190 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &target
)) > 0) {
1192 if (!path_is_normalized(path
))
1193 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1195 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1196 CGroupIODeviceLatency
*a
= NULL
, *b
;
1198 LIST_FOREACH(device_latencies
, b
, c
->io_device_latencies
) {
1199 if (path_equal(b
->path
, path
)) {
1206 a
= new0(CGroupIODeviceLatency
, 1);
1210 a
->path
= strdup(path
);
1215 LIST_PREPEND(device_latencies
, c
->io_device_latencies
, a
);
1218 a
->target_usec
= target
;
1224 r
= sd_bus_message_exit_container(message
);
1228 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1229 _cleanup_free_
char *buf
= NULL
;
1230 _cleanup_fclose_
FILE *f
= NULL
;
1231 char ts
[FORMAT_TIMESPAN_MAX
];
1232 CGroupIODeviceLatency
*a
;
1236 while (c
->io_device_latencies
)
1237 cgroup_context_free_io_device_latency(c
, c
->io_device_latencies
);
1240 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
1242 f
= open_memstream_unlocked(&buf
, &size
);
1246 fputs("IODeviceLatencyTargetSec=\n", f
);
1247 LIST_FOREACH(device_latencies
, a
, c
->io_device_latencies
)
1248 fprintf(f
, "IODeviceLatencyTargetSec=%s %s\n",
1249 a
->path
, format_timespan(ts
, sizeof(ts
), a
->target_usec
, 1));
1251 r
= fflush_and_check(f
);
1254 unit_write_setting(u
, flags
, name
, buf
);
1259 } else if (STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1265 if (streq(name
, "BlockIOWriteBandwidth"))
1268 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1272 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &u64
)) > 0) {
1274 if (!path_is_normalized(path
))
1275 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1277 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1278 CGroupBlockIODeviceBandwidth
*a
= NULL
, *b
;
1280 LIST_FOREACH(device_bandwidths
, b
, c
->blockio_device_bandwidths
) {
1281 if (path_equal(path
, b
->path
)) {
1288 a
= new0(CGroupBlockIODeviceBandwidth
, 1);
1292 a
->rbps
= CGROUP_LIMIT_MAX
;
1293 a
->wbps
= CGROUP_LIMIT_MAX
;
1294 a
->path
= strdup(path
);
1300 LIST_PREPEND(device_bandwidths
, c
->blockio_device_bandwidths
, a
);
1314 r
= sd_bus_message_exit_container(message
);
1318 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1319 CGroupBlockIODeviceBandwidth
*a
;
1320 _cleanup_free_
char *buf
= NULL
;
1321 _cleanup_fclose_
FILE *f
= NULL
;
1325 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
) {
1327 a
->rbps
= CGROUP_LIMIT_MAX
;
1329 a
->wbps
= CGROUP_LIMIT_MAX
;
1333 unit_invalidate_cgroup(u
, CGROUP_MASK_BLKIO
);
1335 f
= open_memstream_unlocked(&buf
, &size
);
1340 fputs("BlockIOReadBandwidth=\n", f
);
1341 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
)
1342 if (a
->rbps
!= CGROUP_LIMIT_MAX
)
1343 fprintf(f
, "BlockIOReadBandwidth=%s %" PRIu64
"\n", a
->path
, a
->rbps
);
1345 fputs("BlockIOWriteBandwidth=\n", f
);
1346 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
)
1347 if (a
->wbps
!= CGROUP_LIMIT_MAX
)
1348 fprintf(f
, "BlockIOWriteBandwidth=%s %" PRIu64
"\n", a
->path
, a
->wbps
);
1351 r
= fflush_and_check(f
);
1355 unit_write_setting(u
, flags
, name
, buf
);
1360 } else if (streq(name
, "BlockIODeviceWeight")) {
1365 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1369 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &weight
)) > 0) {
1371 if (!path_is_normalized(path
))
1372 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1374 if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight
) || weight
== CGROUP_BLKIO_WEIGHT_INVALID
)
1375 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "BlockIODeviceWeight= out of range");
1377 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1378 CGroupBlockIODeviceWeight
*a
= NULL
, *b
;
1380 LIST_FOREACH(device_weights
, b
, c
->blockio_device_weights
) {
1381 if (path_equal(b
->path
, path
)) {
1388 a
= new0(CGroupBlockIODeviceWeight
, 1);
1392 a
->path
= strdup(path
);
1397 LIST_PREPEND(device_weights
, c
->blockio_device_weights
, a
);
1406 r
= sd_bus_message_exit_container(message
);
1410 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1411 _cleanup_free_
char *buf
= NULL
;
1412 _cleanup_fclose_
FILE *f
= NULL
;
1413 CGroupBlockIODeviceWeight
*a
;
1417 while (c
->blockio_device_weights
)
1418 cgroup_context_free_blockio_device_weight(c
, c
->blockio_device_weights
);
1421 unit_invalidate_cgroup(u
, CGROUP_MASK_BLKIO
);
1423 f
= open_memstream_unlocked(&buf
, &size
);
1427 fputs("BlockIODeviceWeight=\n", f
);
1428 LIST_FOREACH(device_weights
, a
, c
->blockio_device_weights
)
1429 fprintf(f
, "BlockIODeviceWeight=%s %" PRIu64
"\n", a
->path
, a
->weight
);
1431 r
= fflush_and_check(f
);
1435 unit_write_setting(u
, flags
, name
, buf
);
1440 } else if (streq(name
, "DevicePolicy")) {
1442 CGroupDevicePolicy p
;
1444 r
= sd_bus_message_read(message
, "s", &policy
);
1448 p
= cgroup_device_policy_from_string(policy
);
1452 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1453 c
->device_policy
= p
;
1454 unit_invalidate_cgroup(u
, CGROUP_MASK_DEVICES
);
1455 unit_write_settingf(u
, flags
, name
, "DevicePolicy=%s", policy
);
1460 } else if (streq(name
, "DeviceAllow")) {
1461 const char *path
, *rwm
;
1464 r
= sd_bus_message_enter_container(message
, 'a', "(ss)");
1468 while ((r
= sd_bus_message_read(message
, "(ss)", &path
, &rwm
)) > 0) {
1470 if (!valid_device_allow_pattern(path
) || strpbrk(path
, WHITESPACE
))
1471 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "DeviceAllow= requires device node or pattern");
1475 else if (!in_charset(rwm
, "rwm"))
1476 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "DeviceAllow= requires combination of rwm flags");
1478 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1479 CGroupDeviceAllow
*a
= NULL
, *b
;
1481 LIST_FOREACH(device_allow
, b
, c
->device_allow
) {
1482 if (path_equal(b
->path
, path
)) {
1489 a
= new0(CGroupDeviceAllow
, 1);
1493 a
->path
= strdup(path
);
1499 LIST_PREPEND(device_allow
, c
->device_allow
, a
);
1502 a
->r
= !!strchr(rwm
, 'r');
1503 a
->w
= !!strchr(rwm
, 'w');
1504 a
->m
= !!strchr(rwm
, 'm');
1512 r
= sd_bus_message_exit_container(message
);
1516 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1517 _cleanup_free_
char *buf
= NULL
;
1518 _cleanup_fclose_
FILE *f
= NULL
;
1519 CGroupDeviceAllow
*a
;
1523 while (c
->device_allow
)
1524 cgroup_context_free_device_allow(c
, c
->device_allow
);
1527 unit_invalidate_cgroup(u
, CGROUP_MASK_DEVICES
);
1529 f
= open_memstream_unlocked(&buf
, &size
);
1533 fputs("DeviceAllow=\n", f
);
1534 LIST_FOREACH(device_allow
, a
, c
->device_allow
)
1535 fprintf(f
, "DeviceAllow=%s %s%s%s\n", a
->path
, a
->r
? "r" : "", a
->w
? "w" : "", a
->m
? "m" : "");
1537 r
= fflush_and_check(f
);
1540 unit_write_setting(u
, flags
, name
, buf
);
1545 } else if (streq(name
, "IPAccounting")) {
1548 r
= sd_bus_message_read(message
, "b", &b
);
1552 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1553 c
->ip_accounting
= b
;
1555 unit_invalidate_cgroup_bpf(u
);
1556 unit_write_settingf(u
, flags
, name
, "IPAccounting=%s", yes_no(b
));
1561 } else if (STR_IN_SET(name
, "IPAddressAllow", "IPAddressDeny")) {
1562 IPAddressAccessItem
**list
;
1565 list
= streq(name
, "IPAddressAllow") ? &c
->ip_address_allow
: &c
->ip_address_deny
;
1567 r
= sd_bus_message_enter_container(message
, 'a', "(iayu)");
1577 r
= sd_bus_message_enter_container(message
, 'r', "iayu");
1583 r
= sd_bus_message_read(message
, "i", &family
);
1587 if (!IN_SET(family
, AF_INET
, AF_INET6
))
1588 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s= expects IPv4 or IPv6 addresses only.", name
);
1590 r
= sd_bus_message_read_array(message
, 'y', &ap
, &an
);
1594 if (an
!= FAMILY_ADDRESS_SIZE(family
))
1595 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "IP address has wrong size for family (%s, expected %zu, got %zu)",
1596 af_to_name(family
), FAMILY_ADDRESS_SIZE(family
), an
);
1598 r
= sd_bus_message_read(message
, "u", &prefixlen
);
1602 if (prefixlen
> FAMILY_ADDRESS_SIZE(family
)*8)
1603 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Prefix length %" PRIu32
" too large for address family %s.", prefixlen
, af_to_name(family
));
1605 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1606 IPAddressAccessItem
*item
;
1608 item
= new0(IPAddressAccessItem
, 1);
1612 item
->family
= family
;
1613 item
->prefixlen
= prefixlen
;
1614 memcpy(&item
->address
, ap
, an
);
1616 LIST_PREPEND(items
, *list
, item
);
1619 r
= sd_bus_message_exit_container(message
);
1626 r
= sd_bus_message_exit_container(message
);
1630 *list
= ip_address_access_reduce(*list
);
1632 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1633 _cleanup_free_
char *buf
= NULL
;
1634 _cleanup_fclose_
FILE *f
= NULL
;
1635 IPAddressAccessItem
*item
;
1639 *list
= ip_address_access_free_all(*list
);
1641 unit_invalidate_cgroup_bpf(u
);
1642 f
= open_memstream_unlocked(&buf
, &size
);
1649 LIST_FOREACH(items
, item
, *list
) {
1650 char buffer
[CONST_MAX(INET_ADDRSTRLEN
, INET6_ADDRSTRLEN
)];
1653 if (!inet_ntop(item
->family
, &item
->address
, buffer
, sizeof(buffer
)))
1654 return errno_or_else(EINVAL
);
1656 fprintf(f
, "%s=%s/%u\n", name
, buffer
, item
->prefixlen
);
1659 r
= fflush_and_check(f
);
1663 unit_write_setting(u
, flags
, name
, buf
);
1669 if (streq(name
, "DisableControllers") || (u
->transient
&& u
->load_state
== UNIT_STUB
))
1670 return bus_cgroup_set_transient_property(u
, c
, name
, message
, flags
, error
);