1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
6 #include "alloc-util.h"
7 #include "bpf-firewall.h"
8 #include "bus-get-properties.h"
9 #include "cgroup-util.h"
11 #include "core-varlink.h"
12 #include "dbus-cgroup.h"
13 #include "dbus-util.h"
14 #include "errno-util.h"
17 #include "limits-util.h"
18 #include "path-util.h"
19 #include "percent-util.h"
21 BUS_DEFINE_PROPERTY_GET(bus_property_get_tasks_max
, "t", TasksMax
, tasks_max_resolve
);
23 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy
, cgroup_device_policy
, CGroupDevicePolicy
);
24 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_managed_oom_mode
, managed_oom_mode
, ManagedOOMMode
);
25 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_managed_oom_preference
, managed_oom_preference
, ManagedOOMPreference
);
27 static int property_get_cgroup_mask(
30 const char *interface
,
32 sd_bus_message
*reply
,
34 sd_bus_error
*error
) {
36 CGroupMask
*mask
= userdata
;
42 r
= sd_bus_message_open_container(reply
, 'a', "s");
46 for (CGroupController ctrl
= 0; ctrl
< _CGROUP_CONTROLLER_MAX
; ctrl
++) {
47 if ((*mask
& CGROUP_CONTROLLER_TO_MASK(ctrl
)) == 0)
50 r
= sd_bus_message_append(reply
, "s", cgroup_controller_to_string(ctrl
));
55 return sd_bus_message_close_container(reply
);
58 static int property_get_delegate_controllers(
61 const char *interface
,
63 sd_bus_message
*reply
,
65 sd_bus_error
*error
) {
67 CGroupContext
*c
= userdata
;
74 return sd_bus_message_append(reply
, "as", 0);
76 return property_get_cgroup_mask(bus
, path
, interface
, property
, reply
, &c
->delegate_controllers
, error
);
79 static int property_get_cpuset(
82 const char *interface
,
84 sd_bus_message
*reply
,
86 sd_bus_error
*error
) {
88 CPUSet
*cpus
= userdata
;
89 _cleanup_free_
uint8_t *array
= NULL
;
96 (void) cpu_set_to_dbus(cpus
, &array
, &allocated
);
97 return sd_bus_message_append_array(reply
, 'y', array
, allocated
);
100 static int property_get_io_device_weight(
103 const char *interface
,
104 const char *property
,
105 sd_bus_message
*reply
,
107 sd_bus_error
*error
) {
109 CGroupContext
*c
= userdata
;
110 CGroupIODeviceWeight
*w
;
117 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
121 LIST_FOREACH(device_weights
, w
, c
->io_device_weights
) {
122 r
= sd_bus_message_append(reply
, "(st)", w
->path
, w
->weight
);
127 return sd_bus_message_close_container(reply
);
130 static int property_get_io_device_limits(
133 const char *interface
,
134 const char *property
,
135 sd_bus_message
*reply
,
137 sd_bus_error
*error
) {
139 CGroupContext
*c
= userdata
;
140 CGroupIODeviceLimit
*l
;
147 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
151 LIST_FOREACH(device_limits
, l
, c
->io_device_limits
) {
152 CGroupIOLimitType type
;
154 type
= cgroup_io_limit_type_from_string(property
);
155 if (type
< 0 || l
->limits
[type
] == cgroup_io_limit_defaults
[type
])
158 r
= sd_bus_message_append(reply
, "(st)", l
->path
, l
->limits
[type
]);
163 return sd_bus_message_close_container(reply
);
166 static int property_get_io_device_latency(
169 const char *interface
,
170 const char *property
,
171 sd_bus_message
*reply
,
173 sd_bus_error
*error
) {
175 CGroupContext
*c
= userdata
;
176 CGroupIODeviceLatency
*l
;
183 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
187 LIST_FOREACH(device_latencies
, l
, c
->io_device_latencies
) {
188 r
= sd_bus_message_append(reply
, "(st)", l
->path
, l
->target_usec
);
193 return sd_bus_message_close_container(reply
);
196 static int property_get_blockio_device_weight(
199 const char *interface
,
200 const char *property
,
201 sd_bus_message
*reply
,
203 sd_bus_error
*error
) {
205 CGroupContext
*c
= userdata
;
206 CGroupBlockIODeviceWeight
*w
;
213 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
217 LIST_FOREACH(device_weights
, w
, c
->blockio_device_weights
) {
218 r
= sd_bus_message_append(reply
, "(st)", w
->path
, w
->weight
);
223 return sd_bus_message_close_container(reply
);
226 static int property_get_blockio_device_bandwidths(
229 const char *interface
,
230 const char *property
,
231 sd_bus_message
*reply
,
233 sd_bus_error
*error
) {
235 CGroupContext
*c
= userdata
;
236 CGroupBlockIODeviceBandwidth
*b
;
243 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
247 LIST_FOREACH(device_bandwidths
, b
, c
->blockio_device_bandwidths
) {
250 if (streq(property
, "BlockIOReadBandwidth"))
255 if (v
== CGROUP_LIMIT_MAX
)
258 r
= sd_bus_message_append(reply
, "(st)", b
->path
, v
);
263 return sd_bus_message_close_container(reply
);
266 static int property_get_device_allow(
269 const char *interface
,
270 const char *property
,
271 sd_bus_message
*reply
,
273 sd_bus_error
*error
) {
275 CGroupContext
*c
= userdata
;
276 CGroupDeviceAllow
*a
;
283 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
287 LIST_FOREACH(device_allow
, a
, c
->device_allow
) {
300 r
= sd_bus_message_append(reply
, "(ss)", a
->path
, rwm
);
305 return sd_bus_message_close_container(reply
);
308 static int property_get_ip_address_access(
311 const char *interface
,
312 const char *property
,
313 sd_bus_message
*reply
,
315 sd_bus_error
*error
) {
317 IPAddressAccessItem
** items
= userdata
, *i
;
320 r
= sd_bus_message_open_container(reply
, 'a', "(iayu)");
324 LIST_FOREACH(items
, i
, *items
) {
326 r
= sd_bus_message_open_container(reply
, 'r', "iayu");
330 r
= sd_bus_message_append(reply
, "i", i
->family
);
334 r
= sd_bus_message_append_array(reply
, 'y', &i
->address
, FAMILY_ADDRESS_SIZE(i
->family
));
338 r
= sd_bus_message_append(reply
, "u", (uint32_t) i
->prefixlen
);
342 r
= sd_bus_message_close_container(reply
);
347 return sd_bus_message_close_container(reply
);
350 const sd_bus_vtable bus_cgroup_vtable
[] = {
351 SD_BUS_VTABLE_START(0),
352 SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool
, offsetof(CGroupContext
, delegate
), 0),
353 SD_BUS_PROPERTY("DelegateControllers", "as", property_get_delegate_controllers
, 0, 0),
354 SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, cpu_accounting
), 0),
355 SD_BUS_PROPERTY("CPUWeight", "t", NULL
, offsetof(CGroupContext
, cpu_weight
), 0),
356 SD_BUS_PROPERTY("StartupCPUWeight", "t", NULL
, offsetof(CGroupContext
, startup_cpu_weight
), 0),
357 SD_BUS_PROPERTY("CPUShares", "t", NULL
, offsetof(CGroupContext
, cpu_shares
), 0),
358 SD_BUS_PROPERTY("StartupCPUShares", "t", NULL
, offsetof(CGroupContext
, startup_cpu_shares
), 0),
359 SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec
, offsetof(CGroupContext
, cpu_quota_per_sec_usec
), 0),
360 SD_BUS_PROPERTY("CPUQuotaPeriodUSec", "t", bus_property_get_usec
, offsetof(CGroupContext
, cpu_quota_period_usec
), 0),
361 SD_BUS_PROPERTY("AllowedCPUs", "ay", property_get_cpuset
, offsetof(CGroupContext
, cpuset_cpus
), 0),
362 SD_BUS_PROPERTY("AllowedMemoryNodes", "ay", property_get_cpuset
, offsetof(CGroupContext
, cpuset_mems
), 0),
363 SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, io_accounting
), 0),
364 SD_BUS_PROPERTY("IOWeight", "t", NULL
, offsetof(CGroupContext
, io_weight
), 0),
365 SD_BUS_PROPERTY("StartupIOWeight", "t", NULL
, offsetof(CGroupContext
, startup_io_weight
), 0),
366 SD_BUS_PROPERTY("IODeviceWeight", "a(st)", property_get_io_device_weight
, 0, 0),
367 SD_BUS_PROPERTY("IOReadBandwidthMax", "a(st)", property_get_io_device_limits
, 0, 0),
368 SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits
, 0, 0),
369 SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits
, 0, 0),
370 SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits
, 0, 0),
371 SD_BUS_PROPERTY("IODeviceLatencyTargetUSec", "a(st)", property_get_io_device_latency
, 0, 0),
372 SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, blockio_accounting
), 0),
373 SD_BUS_PROPERTY("BlockIOWeight", "t", NULL
, offsetof(CGroupContext
, blockio_weight
), 0),
374 SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL
, offsetof(CGroupContext
, startup_blockio_weight
), 0),
375 SD_BUS_PROPERTY("BlockIODeviceWeight", "a(st)", property_get_blockio_device_weight
, 0, 0),
376 SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths
, 0, 0),
377 SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths
, 0, 0),
378 SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, memory_accounting
), 0),
379 SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL
, offsetof(CGroupContext
, default_memory_low
), 0),
380 SD_BUS_PROPERTY("DefaultMemoryMin", "t", NULL
, offsetof(CGroupContext
, default_memory_min
), 0),
381 SD_BUS_PROPERTY("MemoryMin", "t", NULL
, offsetof(CGroupContext
, memory_min
), 0),
382 SD_BUS_PROPERTY("MemoryLow", "t", NULL
, offsetof(CGroupContext
, memory_low
), 0),
383 SD_BUS_PROPERTY("MemoryHigh", "t", NULL
, offsetof(CGroupContext
, memory_high
), 0),
384 SD_BUS_PROPERTY("MemoryMax", "t", NULL
, offsetof(CGroupContext
, memory_max
), 0),
385 SD_BUS_PROPERTY("MemorySwapMax", "t", NULL
, offsetof(CGroupContext
, memory_swap_max
), 0),
386 SD_BUS_PROPERTY("MemoryLimit", "t", NULL
, offsetof(CGroupContext
, memory_limit
), 0),
387 SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy
, offsetof(CGroupContext
, device_policy
), 0),
388 SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow
, 0, 0),
389 SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, tasks_accounting
), 0),
390 SD_BUS_PROPERTY("TasksMax", "t", bus_property_get_tasks_max
, offsetof(CGroupContext
, tasks_max
), 0),
391 SD_BUS_PROPERTY("IPAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, ip_accounting
), 0),
392 SD_BUS_PROPERTY("IPAddressAllow", "a(iayu)", property_get_ip_address_access
, offsetof(CGroupContext
, ip_address_allow
), 0),
393 SD_BUS_PROPERTY("IPAddressDeny", "a(iayu)", property_get_ip_address_access
, offsetof(CGroupContext
, ip_address_deny
), 0),
394 SD_BUS_PROPERTY("IPIngressFilterPath", "as", NULL
, offsetof(CGroupContext
, ip_filters_ingress
), 0),
395 SD_BUS_PROPERTY("IPEgressFilterPath", "as", NULL
, offsetof(CGroupContext
, ip_filters_egress
), 0),
396 SD_BUS_PROPERTY("DisableControllers", "as", property_get_cgroup_mask
, offsetof(CGroupContext
, disable_controllers
), 0),
397 SD_BUS_PROPERTY("ManagedOOMSwap", "s", property_get_managed_oom_mode
, offsetof(CGroupContext
, moom_swap
), 0),
398 SD_BUS_PROPERTY("ManagedOOMMemoryPressure", "s", property_get_managed_oom_mode
, offsetof(CGroupContext
, moom_mem_pressure
), 0),
399 SD_BUS_PROPERTY("ManagedOOMMemoryPressureLimitPermyriad", "u", NULL
, offsetof(CGroupContext
, moom_mem_pressure_limit_permyriad
), 0),
400 SD_BUS_PROPERTY("ManagedOOMPreference", "s", property_get_managed_oom_preference
, offsetof(CGroupContext
, moom_preference
), 0),
404 static int bus_cgroup_set_transient_property(
408 sd_bus_message
*message
,
409 UnitWriteFlags flags
,
410 sd_bus_error
*error
) {
419 flags
|= UNIT_PRIVATE
;
421 if (streq(name
, "Delegate")) {
424 if (!UNIT_VTABLE(u
)->can_delegate
)
425 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Delegation not available for unit type");
427 r
= sd_bus_message_read(message
, "b", &b
);
431 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
433 c
->delegate_controllers
= b
? _CGROUP_MASK_ALL
: 0;
435 unit_write_settingf(u
, flags
, name
, "Delegate=%s", yes_no(b
));
440 } else if (STR_IN_SET(name
, "DelegateControllers", "DisableControllers")) {
443 if (streq(name
, "DelegateControllers") && !UNIT_VTABLE(u
)->can_delegate
)
444 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Delegation not available for unit type");
446 r
= sd_bus_message_enter_container(message
, 'a', "s");
454 r
= sd_bus_message_read(message
, "s", &t
);
460 cc
= cgroup_controller_from_string(t
);
462 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown cgroup controller '%s'", t
);
464 mask
|= CGROUP_CONTROLLER_TO_MASK(cc
);
467 r
= sd_bus_message_exit_container(message
);
471 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
472 _cleanup_free_
char *t
= NULL
;
474 r
= cg_mask_to_string(mask
, &t
);
478 if (streq(name
, "DelegateControllers")) {
482 c
->delegate_controllers
= 0;
484 c
->delegate_controllers
|= mask
;
486 unit_write_settingf(u
, flags
, name
, "Delegate=%s", strempty(t
));
488 } else if (streq(name
, "DisableControllers")) {
491 c
->disable_controllers
= 0;
493 c
->disable_controllers
|= mask
;
495 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, strempty(t
));
500 } else if (STR_IN_SET(name
, "IPIngressFilterPath", "IPEgressFilterPath")) {
504 filters
= streq(name
, "IPIngressFilterPath") ? &c
->ip_filters_ingress
: &c
->ip_filters_egress
;
505 r
= sd_bus_message_enter_container(message
, 'a', "s");
512 r
= sd_bus_message_read(message
, "s", &path
);
518 if (!path_is_normalized(path
) || !path_is_absolute(path
))
519 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s= expects a normalized absolute path.", name
);
521 if (!UNIT_WRITE_FLAGS_NOOP(flags
) && !strv_contains(*filters
, path
)) {
522 r
= strv_extend(filters
, path
);
528 r
= sd_bus_message_exit_container(message
);
532 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
533 _cleanup_free_
char *buf
= NULL
;
534 _cleanup_fclose_
FILE *f
= NULL
;
539 *filters
= strv_free(*filters
);
541 unit_invalidate_cgroup_bpf(u
);
542 f
= open_memstream_unlocked(&buf
, &size
);
549 STRV_FOREACH(entry
, *filters
)
550 fprintf(f
, "%s=%s\n", name
, *entry
);
552 r
= fflush_and_check(f
);
556 unit_write_setting(u
, flags
, name
, buf
);
559 r
= bpf_firewall_supported();
562 if (r
!= BPF_FIREWALL_SUPPORTED_WITH_MULTI
) {
563 static bool warned
= false;
565 log_full(warned
? LOG_DEBUG
: LOG_WARNING
,
566 "Transient unit %s configures an IP firewall with BPF, but the local system does not support BPF/cgroup firewalling with multiple filters.\n"
567 "Starting this unit will fail! (This warning is only shown for the first started transient unit using IP firewalling.)", u
->id
);
579 static int bus_cgroup_set_boolean(
584 sd_bus_message
*message
,
585 UnitWriteFlags flags
,
586 sd_bus_error
*error
) {
592 r
= sd_bus_message_read(message
, "b", &b
);
596 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
598 unit_invalidate_cgroup(u
, mask
);
599 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, yes_no(b
));
605 #define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val) \
606 static int bus_cgroup_set_##function( \
610 sd_bus_message *message, \
611 UnitWriteFlags flags, \
612 sd_bus_error *error) { \
619 r = sd_bus_message_read(message, "t", &v); \
624 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
625 "Value specified in %s is out of range", name); \
627 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
629 unit_invalidate_cgroup(u, mask); \
632 unit_write_settingf(u, flags, name, \
635 unit_write_settingf(u, flags, name, \
636 "%s=%" PRIu64, name, v); \
642 #define BUS_DEFINE_SET_CGROUP_LIMIT(function, mask, scale, minimum) \
643 static int bus_cgroup_set_##function( \
647 sd_bus_message *message, \
648 UnitWriteFlags flags, \
649 sd_bus_error *error) { \
656 r = sd_bus_message_read(message, "t", &v); \
661 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
662 "Value specified in %s is out of range", name); \
664 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
666 unit_invalidate_cgroup(u, mask); \
668 if (v == CGROUP_LIMIT_MAX) \
669 unit_write_settingf(u, flags, name, \
670 "%s=infinity", name); \
672 unit_write_settingf(u, flags, name, \
673 "%s=%" PRIu64, name, v); \
678 static int bus_cgroup_set_##function##_scale( \
682 sd_bus_message *message, \
683 UnitWriteFlags flags, \
684 sd_bus_error *error) { \
692 r = sd_bus_message_read(message, "u", &raw); \
696 v = scale(raw, UINT32_MAX); \
697 if (v < minimum || v >= UINT64_MAX) \
698 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
699 "Value specified in %s is out of range", name); \
701 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
703 unit_invalidate_cgroup(u, mask); \
705 /* Prepare to chop off suffix */ \
706 assert_se(endswith(name, "Scale")); \
708 int scaled = UINT32_SCALE_TO_PERMYRIAD(raw); \
709 unit_write_settingf(u, flags, name, "%.*s=%i.%02i%%", \
710 (int)(strlen(name) - strlen("Scale")), name, \
711 scaled / 100, scaled % 100); \
717 DISABLE_WARNING_TYPE_LIMITS
;
718 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight
, CGROUP_MASK_CPU
, CGROUP_WEIGHT_IS_OK
, CGROUP_WEIGHT_INVALID
);
719 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares
, CGROUP_MASK_CPU
, CGROUP_CPU_SHARES_IS_OK
, CGROUP_CPU_SHARES_INVALID
);
720 BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight
, CGROUP_MASK_IO
, CGROUP_WEIGHT_IS_OK
, CGROUP_WEIGHT_INVALID
);
721 BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight
, CGROUP_MASK_BLKIO
, CGROUP_BLKIO_WEIGHT_IS_OK
, CGROUP_BLKIO_WEIGHT_INVALID
);
722 BUS_DEFINE_SET_CGROUP_LIMIT(memory
, CGROUP_MASK_MEMORY
, physical_memory_scale
, 1);
723 BUS_DEFINE_SET_CGROUP_LIMIT(memory_protection
, CGROUP_MASK_MEMORY
, physical_memory_scale
, 0);
724 BUS_DEFINE_SET_CGROUP_LIMIT(swap
, CGROUP_MASK_MEMORY
, physical_memory_scale
, 0);
727 static int bus_cgroup_set_tasks_max(
731 sd_bus_message
*message
,
732 UnitWriteFlags flags
,
733 sd_bus_error
*error
) {
740 r
= sd_bus_message_read(message
, "t", &v
);
745 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
,
746 "Value specified in %s is out of range", name
);
748 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
749 *p
= (TasksMax
) { .value
= v
, .scale
= 0 }; /* When .scale==0, .value is the absolute value */
750 unit_invalidate_cgroup(u
, CGROUP_MASK_PIDS
);
752 if (v
== CGROUP_LIMIT_MAX
)
753 unit_write_settingf(u
, flags
, name
,
754 "%s=infinity", name
);
756 unit_write_settingf(u
, flags
, name
,
757 "%s=%" PRIu64
, name
, v
);
763 static int bus_cgroup_set_tasks_max_scale(
767 sd_bus_message
*message
,
768 UnitWriteFlags flags
,
769 sd_bus_error
*error
) {
776 r
= sd_bus_message_read(message
, "u", &v
);
780 if (v
< 1 || v
>= UINT32_MAX
)
781 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
,
782 "Value specified in %s is out of range", name
);
784 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
785 *p
= (TasksMax
) { v
, UINT32_MAX
}; /* .scale is not 0, so this is interpreted as v/UINT32_MAX. */
786 unit_invalidate_cgroup(u
, CGROUP_MASK_PIDS
);
788 uint32_t scaled
= DIV_ROUND_UP((uint64_t) v
* 100U, (uint64_t) UINT32_MAX
);
789 unit_write_settingf(u
, flags
, name
, "%s=%" PRIu32
".%" PRIu32
"%%", "TasksMax",
790 scaled
/ 10, scaled
% 10);
796 int bus_cgroup_set_property(
800 sd_bus_message
*message
,
801 UnitWriteFlags flags
,
802 sd_bus_error
*error
) {
804 CGroupIOLimitType iol_type
;
812 flags
|= UNIT_PRIVATE
;
814 if (streq(name
, "CPUAccounting"))
815 return bus_cgroup_set_boolean(u
, name
, &c
->cpu_accounting
, get_cpu_accounting_mask(), message
, flags
, error
);
817 if (streq(name
, "CPUWeight"))
818 return bus_cgroup_set_cpu_weight(u
, name
, &c
->cpu_weight
, message
, flags
, error
);
820 if (streq(name
, "StartupCPUWeight"))
821 return bus_cgroup_set_cpu_weight(u
, name
, &c
->startup_cpu_weight
, message
, flags
, error
);
823 if (streq(name
, "CPUShares"))
824 return bus_cgroup_set_cpu_shares(u
, name
, &c
->cpu_shares
, message
, flags
, error
);
826 if (streq(name
, "StartupCPUShares"))
827 return bus_cgroup_set_cpu_shares(u
, name
, &c
->startup_cpu_shares
, message
, flags
, error
);
829 if (streq(name
, "IOAccounting"))
830 return bus_cgroup_set_boolean(u
, name
, &c
->io_accounting
, CGROUP_MASK_IO
, message
, flags
, error
);
832 if (streq(name
, "IOWeight"))
833 return bus_cgroup_set_io_weight(u
, name
, &c
->io_weight
, message
, flags
, error
);
835 if (streq(name
, "StartupIOWeight"))
836 return bus_cgroup_set_io_weight(u
, name
, &c
->startup_io_weight
, message
, flags
, error
);
838 if (streq(name
, "BlockIOAccounting"))
839 return bus_cgroup_set_boolean(u
, name
, &c
->blockio_accounting
, CGROUP_MASK_BLKIO
, message
, flags
, error
);
841 if (streq(name
, "BlockIOWeight"))
842 return bus_cgroup_set_blockio_weight(u
, name
, &c
->blockio_weight
, message
, flags
, error
);
844 if (streq(name
, "StartupBlockIOWeight"))
845 return bus_cgroup_set_blockio_weight(u
, name
, &c
->startup_blockio_weight
, message
, flags
, error
);
847 if (streq(name
, "MemoryAccounting"))
848 return bus_cgroup_set_boolean(u
, name
, &c
->memory_accounting
, CGROUP_MASK_MEMORY
, message
, flags
, error
);
850 if (streq(name
, "MemoryMin")) {
851 r
= bus_cgroup_set_memory_protection(u
, name
, &c
->memory_min
, message
, flags
, error
);
853 c
->memory_min_set
= true;
857 if (streq(name
, "MemoryLow")) {
858 r
= bus_cgroup_set_memory_protection(u
, name
, &c
->memory_low
, message
, flags
, error
);
860 c
->memory_low_set
= true;
864 if (streq(name
, "DefaultMemoryMin")) {
865 r
= bus_cgroup_set_memory_protection(u
, name
, &c
->default_memory_min
, message
, flags
, error
);
867 c
->default_memory_min_set
= true;
871 if (streq(name
, "DefaultMemoryLow")) {
872 r
= bus_cgroup_set_memory_protection(u
, name
, &c
->default_memory_low
, message
, flags
, error
);
874 c
->default_memory_low_set
= true;
878 if (streq(name
, "MemoryHigh"))
879 return bus_cgroup_set_memory(u
, name
, &c
->memory_high
, message
, flags
, error
);
881 if (streq(name
, "MemorySwapMax"))
882 return bus_cgroup_set_swap(u
, name
, &c
->memory_swap_max
, message
, flags
, error
);
884 if (streq(name
, "MemoryMax"))
885 return bus_cgroup_set_memory(u
, name
, &c
->memory_max
, message
, flags
, error
);
887 if (streq(name
, "MemoryLimit"))
888 return bus_cgroup_set_memory(u
, name
, &c
->memory_limit
, message
, flags
, error
);
890 if (streq(name
, "MemoryMinScale")) {
891 r
= bus_cgroup_set_memory_protection_scale(u
, name
, &c
->memory_min
, message
, flags
, error
);
893 c
->memory_min_set
= true;
897 if (streq(name
, "MemoryLowScale")) {
898 r
= bus_cgroup_set_memory_protection_scale(u
, name
, &c
->memory_low
, message
, flags
, error
);
900 c
->memory_low_set
= true;
904 if (streq(name
, "DefaultMemoryMinScale")) {
905 r
= bus_cgroup_set_memory_protection_scale(u
, name
, &c
->default_memory_min
, message
, flags
, error
);
907 c
->default_memory_min_set
= true;
911 if (streq(name
, "DefaultMemoryLowScale")) {
912 r
= bus_cgroup_set_memory_protection_scale(u
, name
, &c
->default_memory_low
, message
, flags
, error
);
914 c
->default_memory_low_set
= true;
918 if (streq(name
, "MemoryHighScale"))
919 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_high
, message
, flags
, error
);
921 if (streq(name
, "MemorySwapMaxScale"))
922 return bus_cgroup_set_swap_scale(u
, name
, &c
->memory_swap_max
, message
, flags
, error
);
924 if (streq(name
, "MemoryMaxScale"))
925 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_max
, message
, flags
, error
);
927 if (streq(name
, "MemoryLimitScale"))
928 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_limit
, message
, flags
, error
);
930 if (streq(name
, "TasksAccounting"))
931 return bus_cgroup_set_boolean(u
, name
, &c
->tasks_accounting
, CGROUP_MASK_PIDS
, message
, flags
, error
);
933 if (streq(name
, "TasksMax"))
934 return bus_cgroup_set_tasks_max(u
, name
, &c
->tasks_max
, message
, flags
, error
);
936 if (streq(name
, "TasksMaxScale"))
937 return bus_cgroup_set_tasks_max_scale(u
, name
, &c
->tasks_max
, message
, flags
, error
);
939 if (streq(name
, "CPUQuotaPerSecUSec")) {
942 r
= sd_bus_message_read(message
, "t", &u64
);
947 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "CPUQuotaPerSecUSec= value out of range");
949 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
950 c
->cpu_quota_per_sec_usec
= u64
;
951 u
->warned_clamping_cpu_quota_period
= false;
952 unit_invalidate_cgroup(u
, CGROUP_MASK_CPU
);
954 if (c
->cpu_quota_per_sec_usec
== USEC_INFINITY
)
955 unit_write_setting(u
, flags
, "CPUQuota", "CPUQuota=");
957 /* config_parse_cpu_quota() requires an integer, so truncating division is used on
959 unit_write_settingf(u
, flags
, "CPUQuota",
961 (double) (c
->cpu_quota_per_sec_usec
/ 10000));
966 } else if (streq(name
, "CPUQuotaPeriodUSec")) {
969 r
= sd_bus_message_read(message
, "t", &u64
);
973 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
974 c
->cpu_quota_period_usec
= u64
;
975 u
->warned_clamping_cpu_quota_period
= false;
976 unit_invalidate_cgroup(u
, CGROUP_MASK_CPU
);
977 if (c
->cpu_quota_period_usec
== USEC_INFINITY
)
978 unit_write_setting(u
, flags
, "CPUQuotaPeriodSec", "CPUQuotaPeriodSec=");
980 char v
[FORMAT_TIMESPAN_MAX
];
981 unit_write_settingf(u
, flags
, "CPUQuotaPeriodSec",
982 "CPUQuotaPeriodSec=%s",
983 format_timespan(v
, sizeof(v
), c
->cpu_quota_period_usec
, 1));
989 } else if (STR_IN_SET(name
, "AllowedCPUs", "AllowedMemoryNodes")) {
992 _cleanup_(cpu_set_reset
) CPUSet new_set
= {};
994 r
= sd_bus_message_read_array(message
, 'y', &a
, &n
);
998 r
= cpu_set_from_dbus(a
, n
, &new_set
);
1002 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1003 _cleanup_free_
char *setstr
= NULL
;
1006 setstr
= cpu_set_to_range_string(&new_set
);
1010 if (streq(name
, "AllowedCPUs"))
1011 set
= &c
->cpuset_cpus
;
1013 set
= &c
->cpuset_mems
;
1017 new_set
= (CPUSet
) {};
1019 unit_invalidate_cgroup(u
, CGROUP_MASK_CPUSET
);
1020 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, setstr
);
1025 } else if ((iol_type
= cgroup_io_limit_type_from_string(name
)) >= 0) {
1030 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1034 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &u64
)) > 0) {
1036 if (!path_is_normalized(path
))
1037 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1039 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1040 CGroupIODeviceLimit
*a
= NULL
, *b
;
1042 LIST_FOREACH(device_limits
, b
, c
->io_device_limits
) {
1043 if (path_equal(path
, b
->path
)) {
1050 CGroupIOLimitType type
;
1052 a
= new0(CGroupIODeviceLimit
, 1);
1056 a
->path
= strdup(path
);
1062 for (type
= 0; type
< _CGROUP_IO_LIMIT_TYPE_MAX
; type
++)
1063 a
->limits
[type
] = cgroup_io_limit_defaults
[type
];
1065 LIST_PREPEND(device_limits
, c
->io_device_limits
, a
);
1068 a
->limits
[iol_type
] = u64
;
1076 r
= sd_bus_message_exit_container(message
);
1080 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1081 CGroupIODeviceLimit
*a
;
1082 _cleanup_free_
char *buf
= NULL
;
1083 _cleanup_fclose_
FILE *f
= NULL
;
1087 LIST_FOREACH(device_limits
, a
, c
->io_device_limits
)
1088 a
->limits
[iol_type
] = cgroup_io_limit_defaults
[iol_type
];
1091 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
1093 f
= open_memstream_unlocked(&buf
, &size
);
1097 fprintf(f
, "%s=\n", name
);
1098 LIST_FOREACH(device_limits
, a
, c
->io_device_limits
)
1099 if (a
->limits
[iol_type
] != cgroup_io_limit_defaults
[iol_type
])
1100 fprintf(f
, "%s=%s %" PRIu64
"\n", name
, a
->path
, a
->limits
[iol_type
]);
1102 r
= fflush_and_check(f
);
1105 unit_write_setting(u
, flags
, name
, buf
);
1110 } else if (streq(name
, "IODeviceWeight")) {
1115 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1119 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &weight
)) > 0) {
1121 if (!path_is_normalized(path
))
1122 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1124 if (!CGROUP_WEIGHT_IS_OK(weight
) || weight
== CGROUP_WEIGHT_INVALID
)
1125 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "IODeviceWeight= value out of range");
1127 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1128 CGroupIODeviceWeight
*a
= NULL
, *b
;
1130 LIST_FOREACH(device_weights
, b
, c
->io_device_weights
) {
1131 if (path_equal(b
->path
, path
)) {
1138 a
= new0(CGroupIODeviceWeight
, 1);
1142 a
->path
= strdup(path
);
1147 LIST_PREPEND(device_weights
, c
->io_device_weights
, a
);
1156 r
= sd_bus_message_exit_container(message
);
1160 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1161 _cleanup_free_
char *buf
= NULL
;
1162 _cleanup_fclose_
FILE *f
= NULL
;
1163 CGroupIODeviceWeight
*a
;
1167 while (c
->io_device_weights
)
1168 cgroup_context_free_io_device_weight(c
, c
->io_device_weights
);
1171 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
1173 f
= open_memstream_unlocked(&buf
, &size
);
1177 fputs("IODeviceWeight=\n", f
);
1178 LIST_FOREACH(device_weights
, a
, c
->io_device_weights
)
1179 fprintf(f
, "IODeviceWeight=%s %" PRIu64
"\n", a
->path
, a
->weight
);
1181 r
= fflush_and_check(f
);
1184 unit_write_setting(u
, flags
, name
, buf
);
1189 } else if (streq(name
, "IODeviceLatencyTargetUSec")) {
1194 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1198 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &target
)) > 0) {
1200 if (!path_is_normalized(path
))
1201 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1203 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1204 CGroupIODeviceLatency
*a
= NULL
, *b
;
1206 LIST_FOREACH(device_latencies
, b
, c
->io_device_latencies
) {
1207 if (path_equal(b
->path
, path
)) {
1214 a
= new0(CGroupIODeviceLatency
, 1);
1218 a
->path
= strdup(path
);
1223 LIST_PREPEND(device_latencies
, c
->io_device_latencies
, a
);
1226 a
->target_usec
= target
;
1232 r
= sd_bus_message_exit_container(message
);
1236 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1237 _cleanup_free_
char *buf
= NULL
;
1238 _cleanup_fclose_
FILE *f
= NULL
;
1239 char ts
[FORMAT_TIMESPAN_MAX
];
1240 CGroupIODeviceLatency
*a
;
1244 while (c
->io_device_latencies
)
1245 cgroup_context_free_io_device_latency(c
, c
->io_device_latencies
);
1248 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
1250 f
= open_memstream_unlocked(&buf
, &size
);
1254 fputs("IODeviceLatencyTargetSec=\n", f
);
1255 LIST_FOREACH(device_latencies
, a
, c
->io_device_latencies
)
1256 fprintf(f
, "IODeviceLatencyTargetSec=%s %s\n",
1257 a
->path
, format_timespan(ts
, sizeof(ts
), a
->target_usec
, 1));
1259 r
= fflush_and_check(f
);
1262 unit_write_setting(u
, flags
, name
, buf
);
1267 } else if (STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1273 if (streq(name
, "BlockIOWriteBandwidth"))
1276 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1280 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &u64
)) > 0) {
1282 if (!path_is_normalized(path
))
1283 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1285 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1286 CGroupBlockIODeviceBandwidth
*a
= NULL
, *b
;
1288 LIST_FOREACH(device_bandwidths
, b
, c
->blockio_device_bandwidths
) {
1289 if (path_equal(path
, b
->path
)) {
1296 a
= new0(CGroupBlockIODeviceBandwidth
, 1);
1300 a
->rbps
= CGROUP_LIMIT_MAX
;
1301 a
->wbps
= CGROUP_LIMIT_MAX
;
1302 a
->path
= strdup(path
);
1308 LIST_PREPEND(device_bandwidths
, c
->blockio_device_bandwidths
, a
);
1322 r
= sd_bus_message_exit_container(message
);
1326 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1327 CGroupBlockIODeviceBandwidth
*a
;
1328 _cleanup_free_
char *buf
= NULL
;
1329 _cleanup_fclose_
FILE *f
= NULL
;
1333 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
) {
1335 a
->rbps
= CGROUP_LIMIT_MAX
;
1337 a
->wbps
= CGROUP_LIMIT_MAX
;
1341 unit_invalidate_cgroup(u
, CGROUP_MASK_BLKIO
);
1343 f
= open_memstream_unlocked(&buf
, &size
);
1348 fputs("BlockIOReadBandwidth=\n", f
);
1349 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
)
1350 if (a
->rbps
!= CGROUP_LIMIT_MAX
)
1351 fprintf(f
, "BlockIOReadBandwidth=%s %" PRIu64
"\n", a
->path
, a
->rbps
);
1353 fputs("BlockIOWriteBandwidth=\n", f
);
1354 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
)
1355 if (a
->wbps
!= CGROUP_LIMIT_MAX
)
1356 fprintf(f
, "BlockIOWriteBandwidth=%s %" PRIu64
"\n", a
->path
, a
->wbps
);
1359 r
= fflush_and_check(f
);
1363 unit_write_setting(u
, flags
, name
, buf
);
1368 } else if (streq(name
, "BlockIODeviceWeight")) {
1373 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1377 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &weight
)) > 0) {
1379 if (!path_is_normalized(path
))
1380 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1382 if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight
) || weight
== CGROUP_BLKIO_WEIGHT_INVALID
)
1383 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "BlockIODeviceWeight= out of range");
1385 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1386 CGroupBlockIODeviceWeight
*a
= NULL
, *b
;
1388 LIST_FOREACH(device_weights
, b
, c
->blockio_device_weights
) {
1389 if (path_equal(b
->path
, path
)) {
1396 a
= new0(CGroupBlockIODeviceWeight
, 1);
1400 a
->path
= strdup(path
);
1405 LIST_PREPEND(device_weights
, c
->blockio_device_weights
, a
);
1414 r
= sd_bus_message_exit_container(message
);
1418 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1419 _cleanup_free_
char *buf
= NULL
;
1420 _cleanup_fclose_
FILE *f
= NULL
;
1421 CGroupBlockIODeviceWeight
*a
;
1425 while (c
->blockio_device_weights
)
1426 cgroup_context_free_blockio_device_weight(c
, c
->blockio_device_weights
);
1429 unit_invalidate_cgroup(u
, CGROUP_MASK_BLKIO
);
1431 f
= open_memstream_unlocked(&buf
, &size
);
1435 fputs("BlockIODeviceWeight=\n", f
);
1436 LIST_FOREACH(device_weights
, a
, c
->blockio_device_weights
)
1437 fprintf(f
, "BlockIODeviceWeight=%s %" PRIu64
"\n", a
->path
, a
->weight
);
1439 r
= fflush_and_check(f
);
1443 unit_write_setting(u
, flags
, name
, buf
);
1448 } else if (streq(name
, "DevicePolicy")) {
1450 CGroupDevicePolicy p
;
1452 r
= sd_bus_message_read(message
, "s", &policy
);
1456 p
= cgroup_device_policy_from_string(policy
);
1460 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1461 c
->device_policy
= p
;
1462 unit_invalidate_cgroup(u
, CGROUP_MASK_DEVICES
);
1463 unit_write_settingf(u
, flags
, name
, "DevicePolicy=%s", policy
);
1468 } else if (streq(name
, "DeviceAllow")) {
1469 const char *path
, *rwm
;
1472 r
= sd_bus_message_enter_container(message
, 'a', "(ss)");
1476 while ((r
= sd_bus_message_read(message
, "(ss)", &path
, &rwm
)) > 0) {
1478 if (!valid_device_allow_pattern(path
) || strpbrk(path
, WHITESPACE
))
1479 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "DeviceAllow= requires device node or pattern");
1483 else if (!in_charset(rwm
, "rwm"))
1484 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "DeviceAllow= requires combination of rwm flags");
1486 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1487 CGroupDeviceAllow
*a
= NULL
, *b
;
1489 LIST_FOREACH(device_allow
, b
, c
->device_allow
) {
1490 if (path_equal(b
->path
, path
)) {
1497 a
= new0(CGroupDeviceAllow
, 1);
1501 a
->path
= strdup(path
);
1507 LIST_PREPEND(device_allow
, c
->device_allow
, a
);
1510 a
->r
= strchr(rwm
, 'r');
1511 a
->w
= strchr(rwm
, 'w');
1512 a
->m
= strchr(rwm
, 'm');
1520 r
= sd_bus_message_exit_container(message
);
1524 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1525 _cleanup_free_
char *buf
= NULL
;
1526 _cleanup_fclose_
FILE *f
= NULL
;
1527 CGroupDeviceAllow
*a
;
1531 while (c
->device_allow
)
1532 cgroup_context_free_device_allow(c
, c
->device_allow
);
1535 unit_invalidate_cgroup(u
, CGROUP_MASK_DEVICES
);
1537 f
= open_memstream_unlocked(&buf
, &size
);
1541 fputs("DeviceAllow=\n", f
);
1542 LIST_FOREACH(device_allow
, a
, c
->device_allow
)
1543 fprintf(f
, "DeviceAllow=%s %s%s%s\n", a
->path
, a
->r
? "r" : "", a
->w
? "w" : "", a
->m
? "m" : "");
1545 r
= fflush_and_check(f
);
1548 unit_write_setting(u
, flags
, name
, buf
);
1553 } else if (streq(name
, "IPAccounting")) {
1556 r
= sd_bus_message_read(message
, "b", &b
);
1560 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1561 c
->ip_accounting
= b
;
1563 unit_invalidate_cgroup_bpf(u
);
1564 unit_write_settingf(u
, flags
, name
, "IPAccounting=%s", yes_no(b
));
1569 } else if (STR_IN_SET(name
, "IPAddressAllow", "IPAddressDeny")) {
1570 IPAddressAccessItem
**list
;
1573 list
= streq(name
, "IPAddressAllow") ? &c
->ip_address_allow
: &c
->ip_address_deny
;
1575 r
= sd_bus_message_enter_container(message
, 'a', "(iayu)");
1585 r
= sd_bus_message_enter_container(message
, 'r', "iayu");
1591 r
= sd_bus_message_read(message
, "i", &family
);
1595 if (!IN_SET(family
, AF_INET
, AF_INET6
))
1596 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s= expects IPv4 or IPv6 addresses only.", name
);
1598 r
= sd_bus_message_read_array(message
, 'y', &ap
, &an
);
1602 if (an
!= FAMILY_ADDRESS_SIZE(family
))
1603 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "IP address has wrong size for family (%s, expected %zu, got %zu)",
1604 af_to_name(family
), FAMILY_ADDRESS_SIZE(family
), an
);
1606 r
= sd_bus_message_read(message
, "u", &prefixlen
);
1610 if (prefixlen
> FAMILY_ADDRESS_SIZE(family
)*8)
1611 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
));
1613 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1614 IPAddressAccessItem
*item
;
1616 item
= new0(IPAddressAccessItem
, 1);
1620 item
->family
= family
;
1621 item
->prefixlen
= prefixlen
;
1622 memcpy(&item
->address
, ap
, an
);
1624 LIST_PREPEND(items
, *list
, item
);
1627 r
= sd_bus_message_exit_container(message
);
1634 r
= sd_bus_message_exit_container(message
);
1638 *list
= ip_address_access_reduce(*list
);
1640 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1641 _cleanup_free_
char *buf
= NULL
;
1642 _cleanup_fclose_
FILE *f
= NULL
;
1643 IPAddressAccessItem
*item
;
1647 *list
= ip_address_access_free_all(*list
);
1649 unit_invalidate_cgroup_bpf(u
);
1650 f
= open_memstream_unlocked(&buf
, &size
);
1657 LIST_FOREACH(items
, item
, *list
) {
1658 char buffer
[CONST_MAX(INET_ADDRSTRLEN
, INET6_ADDRSTRLEN
)];
1661 if (!inet_ntop(item
->family
, &item
->address
, buffer
, sizeof(buffer
)))
1662 return errno_or_else(EINVAL
);
1664 fprintf(f
, "%s=%s/%u\n", name
, buffer
, item
->prefixlen
);
1667 r
= fflush_and_check(f
);
1671 unit_write_setting(u
, flags
, name
, buf
);
1677 if (STR_IN_SET(name
, "ManagedOOMSwap", "ManagedOOMMemoryPressure")) {
1678 ManagedOOMMode
*cgroup_mode
= streq(name
, "ManagedOOMSwap") ? &c
->moom_swap
: &c
->moom_mem_pressure
;
1682 if (!UNIT_VTABLE(u
)->can_set_managed_oom
)
1683 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Cannot set %s for this unit type", name
);
1685 r
= sd_bus_message_read(message
, "s", &mode
);
1689 m
= managed_oom_mode_from_string(mode
);
1693 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1695 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, mode
);
1698 (void) manager_varlink_send_managed_oom_update(u
);
1702 if (streq(name
, "ManagedOOMMemoryPressureLimitPermyriad")) {
1705 if (!UNIT_VTABLE(u
)->can_set_managed_oom
)
1706 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Cannot set %s for this unit type", name
);
1708 r
= sd_bus_message_read(message
, "u", &v
);
1715 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1716 c
->moom_mem_pressure_limit_permyriad
= v
;
1717 unit_write_settingf(u
, flags
, name
, "ManagedOOMMemoryPressureLimit=%" PRIu32
".%02" PRIu32
"%%", v
/ 100, v
% 100);
1720 if (c
->moom_mem_pressure
== MANAGED_OOM_KILL
)
1721 (void) manager_varlink_send_managed_oom_update(u
);
1726 if (streq(name
, "ManagedOOMPreference")) {
1727 ManagedOOMPreference p
;
1730 r
= sd_bus_message_read(message
, "s", &pref
);
1734 p
= managed_oom_preference_from_string(pref
);
1738 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1739 c
->moom_preference
= p
;
1740 unit_write_settingf(u
, flags
, name
, "ManagedOOMPreference=%s", pref
);
1746 if (streq(name
, "DisableControllers") || (u
->transient
&& u
->load_state
== UNIT_STUB
))
1747 return bus_cgroup_set_transient_property(u
, c
, name
, message
, flags
, error
);