1 /* SPDX-License-Identifier: LGPL-2.1+ */
7 #include "alloc-util.h"
8 #include "bpf-firewall.h"
10 #include "cgroup-util.h"
12 #include "dbus-cgroup.h"
13 #include "dbus-util.h"
16 #include "limits-util.h"
17 #include "path-util.h"
19 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy
, cgroup_device_policy
, CGroupDevicePolicy
);
21 static int property_get_cgroup_mask(
24 const char *interface
,
26 sd_bus_message
*reply
,
28 sd_bus_error
*error
) {
30 CGroupMask
*mask
= userdata
;
31 CGroupController ctrl
;
37 r
= sd_bus_message_open_container(reply
, 'a', "s");
41 for (ctrl
= 0; ctrl
< _CGROUP_CONTROLLER_MAX
; ctrl
++) {
42 if ((*mask
& CGROUP_CONTROLLER_TO_MASK(ctrl
)) == 0)
45 r
= sd_bus_message_append(reply
, "s", cgroup_controller_to_string(ctrl
));
50 return sd_bus_message_close_container(reply
);
53 static int property_get_delegate_controllers(
56 const char *interface
,
58 sd_bus_message
*reply
,
60 sd_bus_error
*error
) {
62 CGroupContext
*c
= userdata
;
69 return sd_bus_message_append(reply
, "as", 0);
71 return property_get_cgroup_mask(bus
, path
, interface
, property
, reply
, &c
->delegate_controllers
, error
);
74 static int property_get_io_device_weight(
77 const char *interface
,
79 sd_bus_message
*reply
,
81 sd_bus_error
*error
) {
83 CGroupContext
*c
= userdata
;
84 CGroupIODeviceWeight
*w
;
91 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
95 LIST_FOREACH(device_weights
, w
, c
->io_device_weights
) {
96 r
= sd_bus_message_append(reply
, "(st)", w
->path
, w
->weight
);
101 return sd_bus_message_close_container(reply
);
104 static int property_get_io_device_limits(
107 const char *interface
,
108 const char *property
,
109 sd_bus_message
*reply
,
111 sd_bus_error
*error
) {
113 CGroupContext
*c
= userdata
;
114 CGroupIODeviceLimit
*l
;
121 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
125 LIST_FOREACH(device_limits
, l
, c
->io_device_limits
) {
126 CGroupIOLimitType type
;
128 type
= cgroup_io_limit_type_from_string(property
);
129 if (type
< 0 || l
->limits
[type
] == cgroup_io_limit_defaults
[type
])
132 r
= sd_bus_message_append(reply
, "(st)", l
->path
, l
->limits
[type
]);
137 return sd_bus_message_close_container(reply
);
140 static int property_get_io_device_latency(
143 const char *interface
,
144 const char *property
,
145 sd_bus_message
*reply
,
147 sd_bus_error
*error
) {
149 CGroupContext
*c
= userdata
;
150 CGroupIODeviceLatency
*l
;
157 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
161 LIST_FOREACH(device_latencies
, l
, c
->io_device_latencies
) {
162 r
= sd_bus_message_append(reply
, "(st)", l
->path
, l
->target_usec
);
167 return sd_bus_message_close_container(reply
);
170 static int property_get_blockio_device_weight(
173 const char *interface
,
174 const char *property
,
175 sd_bus_message
*reply
,
177 sd_bus_error
*error
) {
179 CGroupContext
*c
= userdata
;
180 CGroupBlockIODeviceWeight
*w
;
187 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
191 LIST_FOREACH(device_weights
, w
, c
->blockio_device_weights
) {
192 r
= sd_bus_message_append(reply
, "(st)", w
->path
, w
->weight
);
197 return sd_bus_message_close_container(reply
);
200 static int property_get_blockio_device_bandwidths(
203 const char *interface
,
204 const char *property
,
205 sd_bus_message
*reply
,
207 sd_bus_error
*error
) {
209 CGroupContext
*c
= userdata
;
210 CGroupBlockIODeviceBandwidth
*b
;
217 r
= sd_bus_message_open_container(reply
, 'a', "(st)");
221 LIST_FOREACH(device_bandwidths
, b
, c
->blockio_device_bandwidths
) {
224 if (streq(property
, "BlockIOReadBandwidth"))
229 if (v
== CGROUP_LIMIT_MAX
)
232 r
= sd_bus_message_append(reply
, "(st)", b
->path
, v
);
237 return sd_bus_message_close_container(reply
);
240 static int property_get_device_allow(
243 const char *interface
,
244 const char *property
,
245 sd_bus_message
*reply
,
247 sd_bus_error
*error
) {
249 CGroupContext
*c
= userdata
;
250 CGroupDeviceAllow
*a
;
257 r
= sd_bus_message_open_container(reply
, 'a', "(ss)");
261 LIST_FOREACH(device_allow
, a
, c
->device_allow
) {
274 r
= sd_bus_message_append(reply
, "(ss)", a
->path
, rwm
);
279 return sd_bus_message_close_container(reply
);
282 static int property_get_ip_address_access(
285 const char *interface
,
286 const char *property
,
287 sd_bus_message
*reply
,
289 sd_bus_error
*error
) {
291 IPAddressAccessItem
** items
= userdata
, *i
;
294 r
= sd_bus_message_open_container(reply
, 'a', "(iayu)");
298 LIST_FOREACH(items
, i
, *items
) {
300 r
= sd_bus_message_open_container(reply
, 'r', "iayu");
304 r
= sd_bus_message_append(reply
, "i", i
->family
);
308 r
= sd_bus_message_append_array(reply
, 'y', &i
->address
, FAMILY_ADDRESS_SIZE(i
->family
));
312 r
= sd_bus_message_append(reply
, "u", (uint32_t) i
->prefixlen
);
316 r
= sd_bus_message_close_container(reply
);
321 return sd_bus_message_close_container(reply
);
324 const sd_bus_vtable bus_cgroup_vtable
[] = {
325 SD_BUS_VTABLE_START(0),
326 SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool
, offsetof(CGroupContext
, delegate
), 0),
327 SD_BUS_PROPERTY("DelegateControllers", "as", property_get_delegate_controllers
, 0, 0),
328 SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, cpu_accounting
), 0),
329 SD_BUS_PROPERTY("CPUWeight", "t", NULL
, offsetof(CGroupContext
, cpu_weight
), 0),
330 SD_BUS_PROPERTY("StartupCPUWeight", "t", NULL
, offsetof(CGroupContext
, startup_cpu_weight
), 0),
331 SD_BUS_PROPERTY("CPUShares", "t", NULL
, offsetof(CGroupContext
, cpu_shares
), 0),
332 SD_BUS_PROPERTY("StartupCPUShares", "t", NULL
, offsetof(CGroupContext
, startup_cpu_shares
), 0),
333 SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec
, offsetof(CGroupContext
, cpu_quota_per_sec_usec
), 0),
334 SD_BUS_PROPERTY("CPUQuotaPeriodUSec", "t", bus_property_get_usec
, offsetof(CGroupContext
, cpu_quota_period_usec
), 0),
335 SD_BUS_PROPERTY("IOAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, io_accounting
), 0),
336 SD_BUS_PROPERTY("IOWeight", "t", NULL
, offsetof(CGroupContext
, io_weight
), 0),
337 SD_BUS_PROPERTY("StartupIOWeight", "t", NULL
, offsetof(CGroupContext
, startup_io_weight
), 0),
338 SD_BUS_PROPERTY("IODeviceWeight", "a(st)", property_get_io_device_weight
, 0, 0),
339 SD_BUS_PROPERTY("IOReadBandwidthMax", "a(st)", property_get_io_device_limits
, 0, 0),
340 SD_BUS_PROPERTY("IOWriteBandwidthMax", "a(st)", property_get_io_device_limits
, 0, 0),
341 SD_BUS_PROPERTY("IOReadIOPSMax", "a(st)", property_get_io_device_limits
, 0, 0),
342 SD_BUS_PROPERTY("IOWriteIOPSMax", "a(st)", property_get_io_device_limits
, 0, 0),
343 SD_BUS_PROPERTY("IODeviceLatencyTargetUSec", "a(st)", property_get_io_device_latency
, 0, 0),
344 SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, blockio_accounting
), 0),
345 SD_BUS_PROPERTY("BlockIOWeight", "t", NULL
, offsetof(CGroupContext
, blockio_weight
), 0),
346 SD_BUS_PROPERTY("StartupBlockIOWeight", "t", NULL
, offsetof(CGroupContext
, startup_blockio_weight
), 0),
347 SD_BUS_PROPERTY("BlockIODeviceWeight", "a(st)", property_get_blockio_device_weight
, 0, 0),
348 SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths
, 0, 0),
349 SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths
, 0, 0),
350 SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, memory_accounting
), 0),
351 SD_BUS_PROPERTY("MemoryMin", "t", NULL
, offsetof(CGroupContext
, memory_min
), 0),
352 SD_BUS_PROPERTY("MemoryLow", "t", NULL
, offsetof(CGroupContext
, memory_low
), 0),
353 SD_BUS_PROPERTY("MemoryHigh", "t", NULL
, offsetof(CGroupContext
, memory_high
), 0),
354 SD_BUS_PROPERTY("MemoryMax", "t", NULL
, offsetof(CGroupContext
, memory_max
), 0),
355 SD_BUS_PROPERTY("MemorySwapMax", "t", NULL
, offsetof(CGroupContext
, memory_swap_max
), 0),
356 SD_BUS_PROPERTY("MemoryLimit", "t", NULL
, offsetof(CGroupContext
, memory_limit
), 0),
357 SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy
, offsetof(CGroupContext
, device_policy
), 0),
358 SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow
, 0, 0),
359 SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, tasks_accounting
), 0),
360 SD_BUS_PROPERTY("TasksMax", "t", NULL
, offsetof(CGroupContext
, tasks_max
), 0),
361 SD_BUS_PROPERTY("IPAccounting", "b", bus_property_get_bool
, offsetof(CGroupContext
, ip_accounting
), 0),
362 SD_BUS_PROPERTY("IPAddressAllow", "a(iayu)", property_get_ip_address_access
, offsetof(CGroupContext
, ip_address_allow
), 0),
363 SD_BUS_PROPERTY("IPAddressDeny", "a(iayu)", property_get_ip_address_access
, offsetof(CGroupContext
, ip_address_deny
), 0),
364 SD_BUS_PROPERTY("DisableControllers", "as", property_get_cgroup_mask
, offsetof(CGroupContext
, disable_controllers
), 0),
368 static int bus_cgroup_set_transient_property(
372 sd_bus_message
*message
,
373 UnitWriteFlags flags
,
374 sd_bus_error
*error
) {
383 flags
|= UNIT_PRIVATE
;
385 if (streq(name
, "Delegate")) {
388 if (!UNIT_VTABLE(u
)->can_delegate
)
389 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Delegation not available for unit type");
391 r
= sd_bus_message_read(message
, "b", &b
);
395 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
397 c
->delegate_controllers
= b
? _CGROUP_MASK_ALL
: 0;
399 unit_write_settingf(u
, flags
, name
, "Delegate=%s", yes_no(b
));
404 } else if (streq(name
, "DelegateControllers")) {
407 if (!UNIT_VTABLE(u
)->can_delegate
)
408 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Delegation not available for unit type");
410 r
= sd_bus_message_enter_container(message
, 'a', "s");
418 r
= sd_bus_message_read(message
, "s", &t
);
424 cc
= cgroup_controller_from_string(t
);
426 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Unknown cgroup controller '%s'", t
);
428 mask
|= CGROUP_CONTROLLER_TO_MASK(cc
);
431 r
= sd_bus_message_exit_container(message
);
435 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
436 _cleanup_free_
char *t
= NULL
;
438 r
= cg_mask_to_string(mask
, &t
);
444 c
->delegate_controllers
= 0;
446 c
->delegate_controllers
|= mask
;
448 unit_write_settingf(u
, flags
, name
, "Delegate=%s", strempty(t
));
457 static int bus_cgroup_set_boolean(
462 sd_bus_message
*message
,
463 UnitWriteFlags flags
,
464 sd_bus_error
*error
) {
470 r
= sd_bus_message_read(message
, "b", &b
);
474 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
476 unit_invalidate_cgroup(u
, mask
);
477 unit_write_settingf(u
, flags
, name
, "%s=%s", name
, yes_no(b
));
483 #define BUS_DEFINE_SET_CGROUP_WEIGHT(function, mask, check, val) \
484 static int bus_cgroup_set_##function( \
488 sd_bus_message *message, \
489 UnitWriteFlags flags, \
490 sd_bus_error *error) { \
497 r = sd_bus_message_read(message, "t", &v); \
502 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
503 "Value specified in %s is out of range", name); \
505 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
507 unit_invalidate_cgroup(u, (mask)); \
510 unit_write_settingf(u, flags, name, \
513 unit_write_settingf(u, flags, name, \
514 "%s=%" PRIu64, name, v); \
520 #define BUS_DEFINE_SET_CGROUP_LIMIT(function, mask, scale, minimum) \
521 static int bus_cgroup_set_##function( \
525 sd_bus_message *message, \
526 UnitWriteFlags flags, \
527 sd_bus_error *error) { \
534 r = sd_bus_message_read(message, "t", &v); \
539 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
540 "Value specified in %s is out of range", name); \
542 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
544 unit_invalidate_cgroup(u, (mask)); \
546 if (v == CGROUP_LIMIT_MAX) \
547 unit_write_settingf(u, flags, name, \
548 "%s=infinity", name); \
550 unit_write_settingf(u, flags, name, \
551 "%s=%" PRIu64, name, v); \
556 static int bus_cgroup_set_##function##_scale( \
560 sd_bus_message *message, \
561 UnitWriteFlags flags, \
562 sd_bus_error *error) { \
570 r = sd_bus_message_read(message, "u", &raw); \
574 v = scale(raw, UINT32_MAX); \
575 if (v < minimum || v >= UINT64_MAX) \
576 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, \
577 "Value specified in %s is out of range", name); \
579 if (!UNIT_WRITE_FLAGS_NOOP(flags)) { \
583 unit_invalidate_cgroup(u, (mask)); \
585 /* Chop off suffix */ \
586 assert_se(e = endswith(name, "Scale")); \
587 name = strndupa(name, e - name); \
589 unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, \
590 (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); \
596 #pragma GCC diagnostic push
597 #pragma GCC diagnostic ignored "-Wtype-limits"
598 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_weight
, CGROUP_MASK_CPU
, CGROUP_WEIGHT_IS_OK
, CGROUP_WEIGHT_INVALID
);
599 BUS_DEFINE_SET_CGROUP_WEIGHT(cpu_shares
, CGROUP_MASK_CPU
, CGROUP_CPU_SHARES_IS_OK
, CGROUP_CPU_SHARES_INVALID
);
600 BUS_DEFINE_SET_CGROUP_WEIGHT(io_weight
, CGROUP_MASK_IO
, CGROUP_WEIGHT_IS_OK
, CGROUP_WEIGHT_INVALID
);
601 BUS_DEFINE_SET_CGROUP_WEIGHT(blockio_weight
, CGROUP_MASK_BLKIO
, CGROUP_BLKIO_WEIGHT_IS_OK
, CGROUP_BLKIO_WEIGHT_INVALID
);
602 BUS_DEFINE_SET_CGROUP_LIMIT(memory
, CGROUP_MASK_MEMORY
, physical_memory_scale
, 1);
603 BUS_DEFINE_SET_CGROUP_LIMIT(swap
, CGROUP_MASK_MEMORY
, physical_memory_scale
, 0);
604 BUS_DEFINE_SET_CGROUP_LIMIT(tasks_max
, CGROUP_MASK_PIDS
, system_tasks_max_scale
, 1);
605 #pragma GCC diagnostic pop
607 int bus_cgroup_set_property(
611 sd_bus_message
*message
,
612 UnitWriteFlags flags
,
613 sd_bus_error
*error
) {
615 CGroupIOLimitType iol_type
;
623 flags
|= UNIT_PRIVATE
;
625 if (streq(name
, "CPUAccounting"))
626 return bus_cgroup_set_boolean(u
, name
, &c
->cpu_accounting
, get_cpu_accounting_mask(), message
, flags
, error
);
628 if (streq(name
, "CPUWeight"))
629 return bus_cgroup_set_cpu_weight(u
, name
, &c
->cpu_weight
, message
, flags
, error
);
631 if (streq(name
, "StartupCPUWeight"))
632 return bus_cgroup_set_cpu_weight(u
, name
, &c
->startup_cpu_weight
, message
, flags
, error
);
634 if (streq(name
, "CPUShares"))
635 return bus_cgroup_set_cpu_shares(u
, name
, &c
->cpu_shares
, message
, flags
, error
);
637 if (streq(name
, "StartupCPUShares"))
638 return bus_cgroup_set_cpu_shares(u
, name
, &c
->startup_cpu_shares
, message
, flags
, error
);
640 if (streq(name
, "IOAccounting"))
641 return bus_cgroup_set_boolean(u
, name
, &c
->io_accounting
, CGROUP_MASK_IO
, message
, flags
, error
);
643 if (streq(name
, "IOWeight"))
644 return bus_cgroup_set_io_weight(u
, name
, &c
->io_weight
, message
, flags
, error
);
646 if (streq(name
, "StartupIOWeight"))
647 return bus_cgroup_set_io_weight(u
, name
, &c
->startup_io_weight
, message
, flags
, error
);
649 if (streq(name
, "BlockIOAccounting"))
650 return bus_cgroup_set_boolean(u
, name
, &c
->blockio_accounting
, CGROUP_MASK_BLKIO
, message
, flags
, error
);
652 if (streq(name
, "BlockIOWeight"))
653 return bus_cgroup_set_blockio_weight(u
, name
, &c
->blockio_weight
, message
, flags
, error
);
655 if (streq(name
, "StartupBlockIOWeight"))
656 return bus_cgroup_set_blockio_weight(u
, name
, &c
->startup_blockio_weight
, message
, flags
, error
);
658 if (streq(name
, "MemoryAccounting"))
659 return bus_cgroup_set_boolean(u
, name
, &c
->memory_accounting
, CGROUP_MASK_MEMORY
, message
, flags
, error
);
661 if (streq(name
, "MemoryMin"))
662 return bus_cgroup_set_memory(u
, name
, &c
->memory_min
, message
, flags
, error
);
664 if (streq(name
, "MemoryLow"))
665 return bus_cgroup_set_memory(u
, name
, &c
->memory_low
, message
, flags
, error
);
667 if (streq(name
, "MemoryHigh"))
668 return bus_cgroup_set_memory(u
, name
, &c
->memory_high
, message
, flags
, error
);
670 if (streq(name
, "MemorySwapMax"))
671 return bus_cgroup_set_swap(u
, name
, &c
->memory_swap_max
, message
, flags
, error
);
673 if (streq(name
, "MemoryMax"))
674 return bus_cgroup_set_memory(u
, name
, &c
->memory_max
, message
, flags
, error
);
676 if (streq(name
, "MemoryLimit"))
677 return bus_cgroup_set_memory(u
, name
, &c
->memory_limit
, message
, flags
, error
);
679 if (streq(name
, "MemoryMinScale"))
680 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_min
, message
, flags
, error
);
682 if (streq(name
, "MemoryLowScale"))
683 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_low
, message
, flags
, error
);
685 if (streq(name
, "MemoryHighScale"))
686 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_high
, message
, flags
, error
);
688 if (streq(name
, "MemorySwapMaxScale"))
689 return bus_cgroup_set_swap_scale(u
, name
, &c
->memory_swap_max
, message
, flags
, error
);
691 if (streq(name
, "MemoryMaxScale"))
692 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_max
, message
, flags
, error
);
694 if (streq(name
, "MemoryLimitScale"))
695 return bus_cgroup_set_memory_scale(u
, name
, &c
->memory_limit
, message
, flags
, error
);
697 if (streq(name
, "TasksAccounting"))
698 return bus_cgroup_set_boolean(u
, name
, &c
->tasks_accounting
, CGROUP_MASK_PIDS
, message
, flags
, error
);
700 if (streq(name
, "TasksMax"))
701 return bus_cgroup_set_tasks_max(u
, name
, &c
->tasks_max
, message
, flags
, error
);
703 if (streq(name
, "TasksMaxScale"))
704 return bus_cgroup_set_tasks_max_scale(u
, name
, &c
->tasks_max
, message
, flags
, error
);
706 if (streq(name
, "CPUQuotaPerSecUSec")) {
709 r
= sd_bus_message_read(message
, "t", &u64
);
714 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "CPUQuotaPerSecUSec= value out of range");
716 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
717 c
->cpu_quota_per_sec_usec
= u64
;
718 u
->warned_clamping_cpu_quota_period
= false;
719 unit_invalidate_cgroup(u
, CGROUP_MASK_CPU
);
721 if (c
->cpu_quota_per_sec_usec
== USEC_INFINITY
)
722 unit_write_setting(u
, flags
, "CPUQuota", "CPUQuota=");
724 /* config_parse_cpu_quota() requires an integer, so truncating division is used on
726 unit_write_settingf(u
, flags
, "CPUQuota",
728 (double) (c
->cpu_quota_per_sec_usec
/ 10000));
733 } else if (streq(name
, "CPUQuotaPeriodUSec")) {
736 r
= sd_bus_message_read(message
, "t", &u64
);
740 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
741 c
->cpu_quota_period_usec
= u64
;
742 u
->warned_clamping_cpu_quota_period
= false;
743 unit_invalidate_cgroup(u
, CGROUP_MASK_CPU
);
744 if (c
->cpu_quota_period_usec
== USEC_INFINITY
)
745 unit_write_setting(u
, flags
, "CPUQuotaPeriodSec", "CPUQuotaPeriodSec=");
747 char v
[FORMAT_TIMESPAN_MAX
];
748 unit_write_settingf(u
, flags
, "CPUQuotaPeriodSec",
749 "CPUQuotaPeriodSec=%s",
750 format_timespan(v
, sizeof(v
), c
->cpu_quota_period_usec
, 1));
756 } else if ((iol_type
= cgroup_io_limit_type_from_string(name
)) >= 0) {
761 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
765 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &u64
)) > 0) {
767 if (!path_is_normalized(path
))
768 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
770 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
771 CGroupIODeviceLimit
*a
= NULL
, *b
;
773 LIST_FOREACH(device_limits
, b
, c
->io_device_limits
) {
774 if (path_equal(path
, b
->path
)) {
781 CGroupIOLimitType type
;
783 a
= new0(CGroupIODeviceLimit
, 1);
787 a
->path
= strdup(path
);
793 for (type
= 0; type
< _CGROUP_IO_LIMIT_TYPE_MAX
; type
++)
794 a
->limits
[type
] = cgroup_io_limit_defaults
[type
];
796 LIST_PREPEND(device_limits
, c
->io_device_limits
, a
);
799 a
->limits
[iol_type
] = u64
;
807 r
= sd_bus_message_exit_container(message
);
811 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
812 CGroupIODeviceLimit
*a
;
813 _cleanup_free_
char *buf
= NULL
;
814 _cleanup_fclose_
FILE *f
= NULL
;
818 LIST_FOREACH(device_limits
, a
, c
->io_device_limits
)
819 a
->limits
[iol_type
] = cgroup_io_limit_defaults
[iol_type
];
822 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
824 f
= open_memstream(&buf
, &size
);
828 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
830 fprintf(f
, "%s=\n", name
);
831 LIST_FOREACH(device_limits
, a
, c
->io_device_limits
)
832 if (a
->limits
[iol_type
] != cgroup_io_limit_defaults
[iol_type
])
833 fprintf(f
, "%s=%s %" PRIu64
"\n", name
, a
->path
, a
->limits
[iol_type
]);
835 r
= fflush_and_check(f
);
838 unit_write_setting(u
, flags
, name
, buf
);
843 } else if (streq(name
, "IODeviceWeight")) {
848 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
852 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &weight
)) > 0) {
854 if (!path_is_normalized(path
))
855 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
857 if (!CGROUP_WEIGHT_IS_OK(weight
) || weight
== CGROUP_WEIGHT_INVALID
)
858 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "IODeviceWeight= value out of range");
860 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
861 CGroupIODeviceWeight
*a
= NULL
, *b
;
863 LIST_FOREACH(device_weights
, b
, c
->io_device_weights
) {
864 if (path_equal(b
->path
, path
)) {
871 a
= new0(CGroupIODeviceWeight
, 1);
875 a
->path
= strdup(path
);
880 LIST_PREPEND(device_weights
, c
->io_device_weights
, a
);
889 r
= sd_bus_message_exit_container(message
);
893 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
894 _cleanup_free_
char *buf
= NULL
;
895 _cleanup_fclose_
FILE *f
= NULL
;
896 CGroupIODeviceWeight
*a
;
900 while (c
->io_device_weights
)
901 cgroup_context_free_io_device_weight(c
, c
->io_device_weights
);
904 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
906 f
= open_memstream(&buf
, &size
);
910 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
912 fputs("IODeviceWeight=\n", f
);
913 LIST_FOREACH(device_weights
, a
, c
->io_device_weights
)
914 fprintf(f
, "IODeviceWeight=%s %" PRIu64
"\n", a
->path
, a
->weight
);
916 r
= fflush_and_check(f
);
919 unit_write_setting(u
, flags
, name
, buf
);
924 } else if (streq(name
, "IODeviceLatencyTargetUSec")) {
929 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
933 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &target
)) > 0) {
935 if (!path_is_normalized(path
))
936 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
938 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
939 CGroupIODeviceLatency
*a
= NULL
, *b
;
941 LIST_FOREACH(device_latencies
, b
, c
->io_device_latencies
) {
942 if (path_equal(b
->path
, path
)) {
949 a
= new0(CGroupIODeviceLatency
, 1);
953 a
->path
= strdup(path
);
958 LIST_PREPEND(device_latencies
, c
->io_device_latencies
, a
);
961 a
->target_usec
= target
;
967 r
= sd_bus_message_exit_container(message
);
971 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
972 _cleanup_free_
char *buf
= NULL
;
973 _cleanup_fclose_
FILE *f
= NULL
;
974 char ts
[FORMAT_TIMESPAN_MAX
];
975 CGroupIODeviceLatency
*a
;
979 while (c
->io_device_latencies
)
980 cgroup_context_free_io_device_latency(c
, c
->io_device_latencies
);
983 unit_invalidate_cgroup(u
, CGROUP_MASK_IO
);
985 f
= open_memstream(&buf
, &size
);
989 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
991 fputs("IODeviceLatencyTargetSec=\n", f
);
992 LIST_FOREACH(device_latencies
, a
, c
->io_device_latencies
)
993 fprintf(f
, "IODeviceLatencyTargetSec=%s %s\n",
994 a
->path
, format_timespan(ts
, sizeof(ts
), a
->target_usec
, 1));
996 r
= fflush_and_check(f
);
999 unit_write_setting(u
, flags
, name
, buf
);
1004 } else if (STR_IN_SET(name
, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1010 if (streq(name
, "BlockIOWriteBandwidth"))
1013 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1017 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &u64
)) > 0) {
1019 if (!path_is_normalized(path
))
1020 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1022 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1023 CGroupBlockIODeviceBandwidth
*a
= NULL
, *b
;
1025 LIST_FOREACH(device_bandwidths
, b
, c
->blockio_device_bandwidths
) {
1026 if (path_equal(path
, b
->path
)) {
1033 a
= new0(CGroupBlockIODeviceBandwidth
, 1);
1037 a
->rbps
= CGROUP_LIMIT_MAX
;
1038 a
->wbps
= CGROUP_LIMIT_MAX
;
1039 a
->path
= strdup(path
);
1045 LIST_PREPEND(device_bandwidths
, c
->blockio_device_bandwidths
, a
);
1059 r
= sd_bus_message_exit_container(message
);
1063 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1064 CGroupBlockIODeviceBandwidth
*a
;
1065 _cleanup_free_
char *buf
= NULL
;
1066 _cleanup_fclose_
FILE *f
= NULL
;
1070 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
) {
1072 a
->rbps
= CGROUP_LIMIT_MAX
;
1074 a
->wbps
= CGROUP_LIMIT_MAX
;
1078 unit_invalidate_cgroup(u
, CGROUP_MASK_BLKIO
);
1080 f
= open_memstream(&buf
, &size
);
1084 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
1087 fputs("BlockIOReadBandwidth=\n", f
);
1088 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
)
1089 if (a
->rbps
!= CGROUP_LIMIT_MAX
)
1090 fprintf(f
, "BlockIOReadBandwidth=%s %" PRIu64
"\n", a
->path
, a
->rbps
);
1092 fputs("BlockIOWriteBandwidth=\n", f
);
1093 LIST_FOREACH(device_bandwidths
, a
, c
->blockio_device_bandwidths
)
1094 if (a
->wbps
!= CGROUP_LIMIT_MAX
)
1095 fprintf(f
, "BlockIOWriteBandwidth=%s %" PRIu64
"\n", a
->path
, a
->wbps
);
1098 r
= fflush_and_check(f
);
1102 unit_write_setting(u
, flags
, name
, buf
);
1107 } else if (streq(name
, "BlockIODeviceWeight")) {
1112 r
= sd_bus_message_enter_container(message
, 'a', "(st)");
1116 while ((r
= sd_bus_message_read(message
, "(st)", &path
, &weight
)) > 0) {
1118 if (!path_is_normalized(path
))
1119 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "Path '%s' specified in %s= is not normalized.", name
, path
);
1121 if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight
) || weight
== CGROUP_BLKIO_WEIGHT_INVALID
)
1122 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "BlockIODeviceWeight= out of range");
1124 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1125 CGroupBlockIODeviceWeight
*a
= NULL
, *b
;
1127 LIST_FOREACH(device_weights
, b
, c
->blockio_device_weights
) {
1128 if (path_equal(b
->path
, path
)) {
1135 a
= new0(CGroupBlockIODeviceWeight
, 1);
1139 a
->path
= strdup(path
);
1144 LIST_PREPEND(device_weights
, c
->blockio_device_weights
, a
);
1153 r
= sd_bus_message_exit_container(message
);
1157 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1158 _cleanup_free_
char *buf
= NULL
;
1159 _cleanup_fclose_
FILE *f
= NULL
;
1160 CGroupBlockIODeviceWeight
*a
;
1164 while (c
->blockio_device_weights
)
1165 cgroup_context_free_blockio_device_weight(c
, c
->blockio_device_weights
);
1168 unit_invalidate_cgroup(u
, CGROUP_MASK_BLKIO
);
1170 f
= open_memstream(&buf
, &size
);
1174 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
1176 fputs("BlockIODeviceWeight=\n", f
);
1177 LIST_FOREACH(device_weights
, a
, c
->blockio_device_weights
)
1178 fprintf(f
, "BlockIODeviceWeight=%s %" PRIu64
"\n", a
->path
, a
->weight
);
1180 r
= fflush_and_check(f
);
1184 unit_write_setting(u
, flags
, name
, buf
);
1189 } else if (streq(name
, "DevicePolicy")) {
1191 CGroupDevicePolicy p
;
1193 r
= sd_bus_message_read(message
, "s", &policy
);
1197 p
= cgroup_device_policy_from_string(policy
);
1201 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1202 c
->device_policy
= p
;
1203 unit_invalidate_cgroup(u
, CGROUP_MASK_DEVICES
);
1204 unit_write_settingf(u
, flags
, name
, "DevicePolicy=%s", policy
);
1209 } else if (streq(name
, "DeviceAllow")) {
1210 const char *path
, *rwm
;
1213 r
= sd_bus_message_enter_container(message
, 'a', "(ss)");
1217 while ((r
= sd_bus_message_read(message
, "(ss)", &path
, &rwm
)) > 0) {
1219 if (!valid_device_allow_pattern(path
) || strpbrk(path
, WHITESPACE
))
1220 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "DeviceAllow= requires device node or pattern");
1224 else if (!in_charset(rwm
, "rwm"))
1225 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "DeviceAllow= requires combination of rwm flags");
1227 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1228 CGroupDeviceAllow
*a
= NULL
, *b
;
1230 LIST_FOREACH(device_allow
, b
, c
->device_allow
) {
1231 if (path_equal(b
->path
, path
)) {
1238 a
= new0(CGroupDeviceAllow
, 1);
1242 a
->path
= strdup(path
);
1248 LIST_PREPEND(device_allow
, c
->device_allow
, a
);
1251 a
->r
= !!strchr(rwm
, 'r');
1252 a
->w
= !!strchr(rwm
, 'w');
1253 a
->m
= !!strchr(rwm
, 'm');
1261 r
= sd_bus_message_exit_container(message
);
1265 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1266 _cleanup_free_
char *buf
= NULL
;
1267 _cleanup_fclose_
FILE *f
= NULL
;
1268 CGroupDeviceAllow
*a
;
1272 while (c
->device_allow
)
1273 cgroup_context_free_device_allow(c
, c
->device_allow
);
1276 unit_invalidate_cgroup(u
, CGROUP_MASK_DEVICES
);
1278 f
= open_memstream(&buf
, &size
);
1282 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
1284 fputs("DeviceAllow=\n", f
);
1285 LIST_FOREACH(device_allow
, a
, c
->device_allow
)
1286 fprintf(f
, "DeviceAllow=%s %s%s%s\n", a
->path
, a
->r
? "r" : "", a
->w
? "w" : "", a
->m
? "m" : "");
1288 r
= fflush_and_check(f
);
1291 unit_write_setting(u
, flags
, name
, buf
);
1296 } else if (streq(name
, "IPAccounting")) {
1299 r
= sd_bus_message_read(message
, "b", &b
);
1303 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1304 c
->ip_accounting
= b
;
1306 unit_invalidate_cgroup_bpf(u
);
1307 unit_write_settingf(u
, flags
, name
, "IPAccounting=%s", yes_no(b
));
1312 } else if (STR_IN_SET(name
, "IPAddressAllow", "IPAddressDeny")) {
1313 IPAddressAccessItem
**list
;
1316 list
= streq(name
, "IPAddressAllow") ? &c
->ip_address_allow
: &c
->ip_address_deny
;
1318 r
= sd_bus_message_enter_container(message
, 'a', "(iayu)");
1328 r
= sd_bus_message_enter_container(message
, 'r', "iayu");
1334 r
= sd_bus_message_read(message
, "i", &family
);
1338 if (!IN_SET(family
, AF_INET
, AF_INET6
))
1339 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "%s= expects IPv4 or IPv6 addresses only.", name
);
1341 r
= sd_bus_message_read_array(message
, 'y', &ap
, &an
);
1345 if (an
!= FAMILY_ADDRESS_SIZE(family
))
1346 return sd_bus_error_setf(error
, SD_BUS_ERROR_INVALID_ARGS
, "IP address has wrong size for family (%s, expected %zu, got %zu)",
1347 af_to_name(family
), FAMILY_ADDRESS_SIZE(family
), an
);
1349 r
= sd_bus_message_read(message
, "u", &prefixlen
);
1353 if (prefixlen
> FAMILY_ADDRESS_SIZE(family
)*8)
1354 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
));
1356 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1357 IPAddressAccessItem
*item
;
1359 item
= new0(IPAddressAccessItem
, 1);
1363 item
->family
= family
;
1364 item
->prefixlen
= prefixlen
;
1365 memcpy(&item
->address
, ap
, an
);
1367 LIST_PREPEND(items
, *list
, item
);
1370 r
= sd_bus_message_exit_container(message
);
1377 r
= sd_bus_message_exit_container(message
);
1381 *list
= ip_address_access_reduce(*list
);
1383 if (!UNIT_WRITE_FLAGS_NOOP(flags
)) {
1384 _cleanup_free_
char *buf
= NULL
;
1385 _cleanup_fclose_
FILE *f
= NULL
;
1386 IPAddressAccessItem
*item
;
1390 *list
= ip_address_access_free_all(*list
);
1392 unit_invalidate_cgroup_bpf(u
);
1393 f
= open_memstream(&buf
, &size
);
1397 (void) __fsetlocking(f
, FSETLOCKING_BYCALLER
);
1402 LIST_FOREACH(items
, item
, *list
) {
1403 char buffer
[CONST_MAX(INET_ADDRSTRLEN
, INET6_ADDRSTRLEN
)];
1406 if (!inet_ntop(item
->family
, &item
->address
, buffer
, sizeof(buffer
)))
1407 return errno
> 0 ? -errno
: -EINVAL
;
1409 fprintf(f
, "%s=%s/%u\n", name
, buffer
, item
->prefixlen
);
1412 r
= fflush_and_check(f
);
1416 unit_write_setting(u
, flags
, name
, buf
);
1419 r
= bpf_firewall_supported();
1422 if (r
== BPF_FIREWALL_UNSUPPORTED
) {
1423 static bool warned
= false;
1425 log_full(warned
? LOG_DEBUG
: LOG_WARNING
,
1426 "Transient unit %s configures an IP firewall, but the local system does not support BPF/cgroup firewalling.\n"
1427 "Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first started transient unit using IP firewalling.)", u
->id
);
1437 if (u
->transient
&& u
->load_state
== UNIT_STUB
)
1438 return bus_cgroup_set_transient_property(u
, c
, name
, message
, flags
, error
);