diff options
author | Michael Biebl <biebl@debian.org> | 2017-12-14 23:22:02 +0100 |
---|---|---|
committer | Michael Biebl <biebl@debian.org> | 2017-12-14 23:22:02 +0100 |
commit | 52ad194e0b816b8273dd8d0fea3e6d467f6ca34e (patch) | |
tree | 1a3b3117e015f200ca0ce23f5ad27be6d0a7b0fb /src/core/dbus-cgroup.c | |
parent | f5e65279187b6aa0c0c5a00b14dca9eab441ffb2 (diff) | |
download | systemd-52ad194e0b816b8273dd8d0fea3e6d467f6ca34e.tar.gz |
New upstream version 236
Diffstat (limited to 'src/core/dbus-cgroup.c')
-rw-r--r-- | src/core/dbus-cgroup.c | 356 |
1 files changed, 235 insertions, 121 deletions
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c index a99d727f4d..abca4e112d 100644 --- a/src/core/dbus-cgroup.c +++ b/src/core/dbus-cgroup.c @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ /*** This file is part of systemd. @@ -18,6 +19,7 @@ ***/ #include <arpa/inet.h> +#include <stdio_ext.h> #include "af-list.h" #include "alloc-util.h" @@ -32,6 +34,42 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_cgroup_device_policy, cgroup_device_policy, CGroupDevicePolicy); +static int property_get_delegate_controllers( + sd_bus *bus, + const char *path, + const char *interface, + const char *property, + sd_bus_message *reply, + void *userdata, + sd_bus_error *error) { + + CGroupContext *c = userdata; + CGroupController cc; + int r; + + assert(bus); + assert(reply); + assert(c); + + if (!c->delegate) + return sd_bus_message_append(reply, "as", 0); + + r = sd_bus_message_open_container(reply, 'a', "s"); + if (r < 0) + return r; + + for (cc = 0; cc < _CGROUP_CONTROLLER_MAX; cc++) { + if ((c->delegate_controllers & CGROUP_CONTROLLER_TO_MASK(cc)) == 0) + continue; + + r = sd_bus_message_append(reply, "s", cgroup_controller_to_string(cc)); + if (r < 0) + return r; + } + + return sd_bus_message_close_container(reply); +} + static int property_get_io_device_weight( sd_bus *bus, const char *path, @@ -255,6 +293,7 @@ static int property_get_ip_address_access( const sd_bus_vtable bus_cgroup_vtable[] = { SD_BUS_VTABLE_START(0), SD_BUS_PROPERTY("Delegate", "b", bus_property_get_bool, offsetof(CGroupContext, delegate), 0), + SD_BUS_PROPERTY("DelegateControllers", "as", property_get_delegate_controllers, 0, 0), SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpu_accounting), 0), SD_BUS_PROPERTY("CPUWeight", "t", NULL, offsetof(CGroupContext, cpu_weight), 0), SD_BUS_PROPERTY("StartupCPUWeight", "t", NULL, offsetof(CGroupContext, startup_cpu_weight), 0), @@ -296,7 +335,7 @@ static int bus_cgroup_set_transient_property( CGroupContext *c, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { int r; @@ -306,6 +345,8 @@ static int bus_cgroup_set_transient_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "Delegate")) { int b; @@ -313,9 +354,57 @@ static int bus_cgroup_set_transient_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->delegate = b; - unit_write_drop_in_private(u, mode, name, b ? "Delegate=yes" : "Delegate=no"); + c->delegate_controllers = b ? _CGROUP_MASK_ALL : 0; + + unit_write_settingf(u, flags, name, "Delegate=%s", yes_no(b)); + } + + return 1; + + } else if (streq(name, "DelegateControllers")) { + CGroupMask mask = 0; + + r = sd_bus_message_enter_container(message, 'a', "s"); + if (r < 0) + return r; + + for (;;) { + CGroupController cc; + const char *t; + + r = sd_bus_message_read(message, "s", &t); + if (r < 0) + return r; + if (r == 0) + break; + + cc = cgroup_controller_from_string(t); + if (cc < 0) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown cgroup contoller '%s'", t); + + mask |= CGROUP_CONTROLLER_TO_MASK(cc); + } + + r = sd_bus_message_exit_container(message); + if (r < 0) + return r; + + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { + _cleanup_free_ char *t = NULL; + + r = cg_mask_to_string(mask, &t); + if (r < 0) + return r; + + c->delegate = true; + if (mask == 0) + c->delegate_controllers = 0; + else + c->delegate_controllers |= mask; + + unit_write_settingf(u, flags, name, "Delegate=%s", strempty(t)); } return 1; @@ -329,7 +418,7 @@ int bus_cgroup_set_property( CGroupContext *c, const char *name, sd_bus_message *message, - UnitSetPropertiesMode mode, + UnitWriteFlags flags, sd_bus_error *error) { CGroupIOLimitType iol_type; @@ -340,6 +429,8 @@ int bus_cgroup_set_property( assert(name); assert(message); + flags |= UNIT_PRIVATE; + if (streq(name, "CPUAccounting")) { int b; @@ -347,10 +438,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_CPUACCT|CGROUP_MASK_CPU); - unit_write_drop_in_private(u, mode, name, b ? "CPUAccounting=yes" : "CPUAccounting=no"); + unit_write_settingf(u, flags, name, "CPUAccounting=%s", yes_no(b)); } return 1; @@ -363,16 +454,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "CPUWeight value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); if (weight == CGROUP_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "CPUWeight="); + unit_write_setting(u, flags, name, "CPUWeight="); else - unit_write_drop_in_private_format(u, mode, name, "CPUWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "CPUWeight=%" PRIu64, weight); } return 1; @@ -385,16 +476,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUWeight value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupCPUWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->startup_cpu_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); if (weight == CGROUP_CPU_SHARES_INVALID) - unit_write_drop_in_private(u, mode, name, "StartupCPUWeight="); + unit_write_setting(u, flags, name, "StartupCPUWeight="); else - unit_write_drop_in_private_format(u, mode, name, "StartupCPUWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "StartupCPUWeight=%" PRIu64, weight); } return 1; @@ -407,16 +498,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_CPU_SHARES_IS_OK(shares)) - return sd_bus_error_set_errnof(error, EINVAL, "CPUShares value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUShares= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_shares = shares; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); if (shares == CGROUP_CPU_SHARES_INVALID) - unit_write_drop_in_private(u, mode, name, "CPUShares="); + unit_write_setting(u, flags, name, "CPUShares="); else - unit_write_drop_in_private_format(u, mode, name, "CPUShares=%" PRIu64, shares); + unit_write_settingf(u, flags, name, "CPUShares=%" PRIu64, shares); } return 1; @@ -429,16 +520,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_CPU_SHARES_IS_OK(shares)) - return sd_bus_error_set_errnof(error, EINVAL, "StartupCPUShares value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupCPUShares= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->startup_cpu_shares = shares; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); if (shares == CGROUP_CPU_SHARES_INVALID) - unit_write_drop_in_private(u, mode, name, "StartupCPUShares="); + unit_write_setting(u, flags, name, "StartupCPUShares="); else - unit_write_drop_in_private_format(u, mode, name, "StartupCPUShares=%" PRIu64, shares); + unit_write_settingf(u, flags, name, "StartupCPUShares=%" PRIu64, shares); } return 1; @@ -451,20 +542,20 @@ int bus_cgroup_set_property( return r; if (u64 <= 0) - return sd_bus_error_set_errnof(error, EINVAL, "CPUQuotaPerSecUSec value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "CPUQuotaPerSecUSec= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->cpu_quota_per_sec_usec = u64; unit_invalidate_cgroup(u, CGROUP_MASK_CPU); + if (c->cpu_quota_per_sec_usec == USEC_INFINITY) - unit_write_drop_in_private_format(u, mode, "CPUQuota", - "CPUQuota="); + unit_write_setting(u, flags, "CPUQuota", "CPUQuota="); else - /* config_parse_cpu_quota() requires an integer, so - * truncating division is used on purpose here. */ - unit_write_drop_in_private_format(u, mode, "CPUQuota", - "CPUQuota=%0.f%%", - (double) (c->cpu_quota_per_sec_usec / 10000)); + /* config_parse_cpu_quota() requires an integer, so truncating division is used on + * purpose here. */ + unit_write_settingf(u, flags, "CPUQuota", + "CPUQuota=%0.f%%", + (double) (c->cpu_quota_per_sec_usec / 10000)); } return 1; @@ -476,10 +567,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->io_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_IO); - unit_write_drop_in_private(u, mode, name, b ? "IOAccounting=yes" : "IOAccounting=no"); + unit_write_settingf(u, flags, name, "IOAccounting=%s", yes_no(b)); } return 1; @@ -492,16 +583,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "IOWeight value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IOWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->io_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_IO); if (weight == CGROUP_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "IOWeight="); + unit_write_setting(u, flags, name, "IOWeight="); else - unit_write_drop_in_private_format(u, mode, name, "IOWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "IOWeight=%" PRIu64, weight); } return 1; @@ -514,16 +605,16 @@ int bus_cgroup_set_property( return r; if (CGROUP_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "StartupIOWeight value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupIOWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->startup_io_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_IO); if (weight == CGROUP_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "StartupIOWeight="); + unit_write_setting(u, flags, name, "StartupIOWeight="); else - unit_write_drop_in_private_format(u, mode, name, "StartupIOWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "StartupIOWeight=%" PRIu64, weight); } return 1; @@ -539,7 +630,7 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) { - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupIODeviceLimit *a = NULL, *b; LIST_FOREACH(device_limits, b, c->io_device_limits) { @@ -580,7 +671,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupIODeviceLimit *a; _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -597,6 +688,8 @@ int bus_cgroup_set_property( if (!f) return -ENOMEM; + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + fprintf(f, "%s=\n", name); LIST_FOREACH(device_limits, a, c->io_device_limits) if (a->limits[iol_type] != cgroup_io_limit_defaults[iol_type]) @@ -605,7 +698,7 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + unit_write_setting(u, flags, name, buf); } return 1; @@ -622,9 +715,9 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) { if (!CGROUP_WEIGHT_IS_OK(weight) || weight == CGROUP_WEIGHT_INVALID) - return sd_bus_error_set_errnof(error, EINVAL, "IODeviceWeight out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IODeviceWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupIODeviceWeight *a = NULL, *b; LIST_FOREACH(device_weights, b, c->io_device_weights) { @@ -657,7 +750,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; CGroupIODeviceWeight *a; @@ -674,14 +767,16 @@ int bus_cgroup_set_property( if (!f) return -ENOMEM; - fputs_unlocked("IODeviceWeight=\n", f); + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + fputs("IODeviceWeight=\n", f); LIST_FOREACH(device_weights, a, c->io_device_weights) fprintf(f, "IODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight); r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + unit_write_setting(u, flags, name, buf); } return 1; @@ -693,10 +788,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->blockio_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); - unit_write_drop_in_private(u, mode, name, b ? "BlockIOAccounting=yes" : "BlockIOAccounting=no"); + unit_write_settingf(u, flags, name, "BlockIOAccounting=%s", yes_no(b)); } return 1; @@ -709,16 +804,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "BlockIOWeight value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "BlockIOWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->blockio_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); if (weight == CGROUP_BLKIO_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "BlockIOWeight="); + unit_write_setting(u, flags, name, "BlockIOWeight="); else - unit_write_drop_in_private_format(u, mode, name, "BlockIOWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "BlockIOWeight=%" PRIu64, weight); } return 1; @@ -731,16 +826,16 @@ int bus_cgroup_set_property( return r; if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight)) - return sd_bus_error_set_errnof(error, EINVAL, "StartupBlockIOWeight value out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "StartupBlockIOWeight= value out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->startup_blockio_weight = weight; unit_invalidate_cgroup(u, CGROUP_MASK_BLKIO); if (weight == CGROUP_BLKIO_WEIGHT_INVALID) - unit_write_drop_in_private(u, mode, name, "StartupBlockIOWeight="); + unit_write_setting(u, flags, name, "StartupBlockIOWeight="); else - unit_write_drop_in_private_format(u, mode, name, "StartupBlockIOWeight=%" PRIu64, weight); + unit_write_settingf(u, flags, name, "StartupBlockIOWeight=%" PRIu64, weight); } return 1; @@ -760,7 +855,7 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &u64)) > 0) { - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupBlockIODeviceBandwidth *a = NULL, *b; LIST_FOREACH(device_bandwidths, b, c->blockio_device_bandwidths) { @@ -801,7 +896,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupBlockIODeviceBandwidth *a; _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; @@ -822,13 +917,15 @@ int bus_cgroup_set_property( if (!f) return -ENOMEM; + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + if (read) { - fputs_unlocked("BlockIOReadBandwidth=\n", f); + fputs("BlockIOReadBandwidth=\n", f); LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths) if (a->rbps != CGROUP_LIMIT_MAX) fprintf(f, "BlockIOReadBandwidth=%s %" PRIu64 "\n", a->path, a->rbps); } else { - fputs_unlocked("BlockIOWriteBandwidth=\n", f); + fputs("BlockIOWriteBandwidth=\n", f); LIST_FOREACH(device_bandwidths, a, c->blockio_device_bandwidths) if (a->wbps != CGROUP_LIMIT_MAX) fprintf(f, "BlockIOWriteBandwidth=%s %" PRIu64 "\n", a->path, a->wbps); @@ -837,7 +934,8 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + + unit_write_setting(u, flags, name, buf); } return 1; @@ -854,9 +952,9 @@ int bus_cgroup_set_property( while ((r = sd_bus_message_read(message, "(st)", &path, &weight)) > 0) { if (!CGROUP_BLKIO_WEIGHT_IS_OK(weight) || weight == CGROUP_BLKIO_WEIGHT_INVALID) - return sd_bus_error_set_errnof(error, EINVAL, "BlockIODeviceWeight out of range"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "BlockIODeviceWeight= out of range"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupBlockIODeviceWeight *a = NULL, *b; LIST_FOREACH(device_weights, b, c->blockio_device_weights) { @@ -889,7 +987,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; CGroupBlockIODeviceWeight *a; @@ -906,14 +1004,17 @@ int bus_cgroup_set_property( if (!f) return -ENOMEM; - fputs_unlocked("BlockIODeviceWeight=\n", f); + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + fputs("BlockIODeviceWeight=\n", f); LIST_FOREACH(device_weights, a, c->blockio_device_weights) fprintf(f, "BlockIODeviceWeight=%s %" PRIu64 "\n", a->path, a->weight); r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + + unit_write_setting(u, flags, name, buf); } return 1; @@ -925,10 +1026,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->memory_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_drop_in_private(u, mode, name, b ? "MemoryAccounting=yes" : "MemoryAccounting=no"); + unit_write_settingf(u, flags, name, "MemoryAccounting=%s", yes_no(b)); } return 1; @@ -940,9 +1041,9 @@ int bus_cgroup_set_property( if (r < 0) return r; if (v <= 0) - return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { if (streq(name, "MemoryLow")) c->memory_low = v; else if (streq(name, "MemoryHigh")) @@ -955,14 +1056,14 @@ int bus_cgroup_set_property( unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); if (v == CGROUP_LIMIT_MAX) - unit_write_drop_in_private_format(u, mode, name, "%s=infinity", name); + unit_write_settingf(u, flags, name, "%s=infinity", name); else - unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, v); + unit_write_settingf(u, flags, name, "%s=%" PRIu64, name, v); } return 1; - } else if (STR_IN_SET(name, "MemoryLowScale", "MemoryHighScale", "MemoryMaxScale")) { + } else if (STR_IN_SET(name, "MemoryLowScale", "MemoryHighScale", "MemoryMaxScale", "MemorySwapMaxScale")) { uint32_t raw; uint64_t v; @@ -972,9 +1073,9 @@ int bus_cgroup_set_property( v = physical_memory_scale(raw, UINT32_MAX); if (v <= 0 || v == UINT64_MAX) - return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { const char *e; /* Chop off suffix */ @@ -985,12 +1086,14 @@ int bus_cgroup_set_property( c->memory_low = v; else if (streq(name, "MemoryHigh")) c->memory_high = v; - else + else if (streq(name, "MemorySwapMaxScale")) + c->memory_swap_max = v; + else /* MemoryMax */ c->memory_max = v; unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu32 "%%", name, - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); + unit_write_settingf(u, flags, name, "%s=%" PRIu32 "%%", name, + (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); } return 1; @@ -1002,16 +1105,16 @@ int bus_cgroup_set_property( if (r < 0) return r; if (limit <= 0) - return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->memory_limit = limit; unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - if (limit == (uint64_t) -1) - unit_write_drop_in_private(u, mode, name, "MemoryLimit=infinity"); + if (limit == CGROUP_LIMIT_MAX) + unit_write_setting(u, flags, name, "MemoryLimit=infinity"); else - unit_write_drop_in_private_format(u, mode, name, "MemoryLimit=%" PRIu64, limit); + unit_write_settingf(u, flags, name, "MemoryLimit=%" PRIu64, limit); } return 1; @@ -1026,12 +1129,12 @@ int bus_cgroup_set_property( limit = physical_memory_scale(raw, UINT32_MAX); if (limit <= 0 || limit == UINT64_MAX) - return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->memory_limit = limit; unit_invalidate_cgroup(u, CGROUP_MASK_MEMORY); - unit_write_drop_in_private_format(u, mode, "MemoryLimit", "MemoryLimit=%" PRIu32 "%%", + unit_write_settingf(u, flags, "MemoryLimit", "MemoryLimit=%" PRIu32 "%%", (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); } @@ -1049,10 +1152,10 @@ int bus_cgroup_set_property( if (p < 0) return -EINVAL; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->device_policy = p; unit_invalidate_cgroup(u, CGROUP_MASK_DEVICES); - unit_write_drop_in_private_format(u, mode, name, "DevicePolicy=%s", policy); + unit_write_settingf(u, flags, name, "DevicePolicy=%s", policy); } return 1; @@ -1072,15 +1175,15 @@ int bus_cgroup_set_property( !startswith(path, "block-") && !startswith(path, "char-")) || strpbrk(path, WHITESPACE)) - return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires device node"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node"); if (isempty(rwm)) rwm = "rwm"; if (!in_charset(rwm, "rwm")) - return sd_bus_error_set_errnof(error, EINVAL, "DeviceAllow= requires combination of rwm flags"); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires combination of rwm flags"); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { CGroupDeviceAllow *a = NULL, *b; LIST_FOREACH(device_allow, b, c->device_allow) { @@ -1118,7 +1221,7 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; CGroupDeviceAllow *a; @@ -1135,14 +1238,16 @@ int bus_cgroup_set_property( if (!f) return -ENOMEM; - fputs_unlocked("DeviceAllow=\n", f); + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + fputs("DeviceAllow=\n", f); LIST_FOREACH(device_allow, a, c->device_allow) fprintf(f, "DeviceAllow=%s %s%s%s\n", a->path, a->r ? "r" : "", a->w ? "w" : "", a->m ? "m" : ""); r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + unit_write_setting(u, flags, name, buf); } return 1; @@ -1154,10 +1259,10 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->tasks_accounting = b; unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - unit_write_drop_in_private(u, mode, name, b ? "TasksAccounting=yes" : "TasksAccounting=no"); + unit_write_settingf(u, flags, name, "TasksAccounting=%s", yes_no(b)); } return 1; @@ -1169,16 +1274,16 @@ int bus_cgroup_set_property( if (r < 0) return r; if (limit <= 0) - return sd_bus_error_set_errnof(error, EINVAL, "%s= is too small", name); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is too small", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->tasks_max = limit; unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); if (limit == (uint64_t) -1) - unit_write_drop_in_private(u, mode, name, "TasksMax=infinity"); + unit_write_setting(u, flags, name, "TasksMax=infinity"); else - unit_write_drop_in_private_format(u, mode, name, "TasksMax=%" PRIu64, limit); + unit_write_settingf(u, flags, name, "TasksMax=%" PRIu64, limit); } return 1; @@ -1193,13 +1298,13 @@ int bus_cgroup_set_property( limit = system_tasks_max_scale(raw, UINT32_MAX); if (limit <= 0 || limit >= UINT64_MAX) - return sd_bus_error_set_errnof(error, EINVAL, "%s= is out of range", name); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= is out of range", name); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->tasks_max = limit; unit_invalidate_cgroup(u, CGROUP_MASK_PIDS); - unit_write_drop_in_private_format(u, mode, name, "TasksMax=%" PRIu32 "%%", - (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); + unit_write_settingf(u, flags, name, "TasksMax=%" PRIu32 "%%", + (uint32_t) (DIV_ROUND_UP((uint64_t) raw * 100U, (uint64_t) UINT32_MAX))); } return 1; @@ -1211,11 +1316,11 @@ int bus_cgroup_set_property( if (r < 0) return r; - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->ip_accounting = b; unit_invalidate_cgroup_bpf(u); - unit_write_drop_in_private(u, mode, name, b ? "IPAccounting=yes" : "IPAccounting=no"); + unit_write_settingf(u, flags, name, "IPAccounting=%s", yes_no(b)); } return 1; @@ -1247,14 +1352,14 @@ int bus_cgroup_set_property( return r; if (!IN_SET(family, AF_INET, AF_INET6)) - return sd_bus_error_set_errnof(error, EINVAL, "%s= expects IPv4 or IPv6 addresses only.", name); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= expects IPv4 or IPv6 addresses only.", name); r = sd_bus_message_read_array(message, 'y', &ap, &an); if (r < 0) return r; if (an != FAMILY_ADDRESS_SIZE(family)) - return sd_bus_error_set_errnof(error, EINVAL, "IP address has wrong size for family (%s, expected %zu, got %zu)", + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "IP address has wrong size for family (%s, expected %zu, got %zu)", af_to_name(family), FAMILY_ADDRESS_SIZE(family), an); r = sd_bus_message_read(message, "u", &prefixlen); @@ -1262,9 +1367,9 @@ int bus_cgroup_set_property( return r; if (prefixlen > FAMILY_ADDRESS_SIZE(family)*8) - return sd_bus_error_set_errnof(error, EINVAL, "Prefix length %" PRIu32 " too large for address family %s.", prefixlen, af_to_name(family)); + 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)); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { IPAddressAccessItem *item; item = new0(IPAddressAccessItem, 1); @@ -1291,7 +1396,7 @@ int bus_cgroup_set_property( *list = ip_address_access_reduce(*list); - if (mode != UNIT_CHECK) { + if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *buf = NULL; _cleanup_fclose_ FILE *f = NULL; IPAddressAccessItem *item; @@ -1305,8 +1410,10 @@ int bus_cgroup_set_property( if (!f) return -ENOMEM; - fputs_unlocked(name, f); - fputs_unlocked("=\n", f); + (void) __fsetlocking(f, FSETLOCKING_BYCALLER); + + fputs(name, f); + fputs("=\n", f); LIST_FOREACH(items, item, *list) { char buffer[CONST_MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN)]; @@ -1321,15 +1428,22 @@ int bus_cgroup_set_property( r = fflush_and_check(f); if (r < 0) return r; - unit_write_drop_in_private(u, mode, name, buf); + + unit_write_setting(u, flags, name, buf); if (*list) { r = bpf_firewall_supported(); if (r < 0) return r; - if (r == 0) - log_warning("Transient unit %s configures an IP firewall, but the local system does not support BPF/cgroup firewalling.\n" - "Proceeding WITHOUT firewalling in effect!", u->id); + if (r == 0) { + static bool warned = false; + + log_full(warned ? LOG_DEBUG : LOG_WARNING, + "Transient unit %s configures an IP firewall, but the local system does not support BPF/cgroup firewalling.\n" + "Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first started transient unit using IP firewalling.)", u->id); + + warned = true; + } } } @@ -1337,7 +1451,7 @@ int bus_cgroup_set_property( } if (u->transient && u->load_state == UNIT_STUB) { - r = bus_cgroup_set_transient_property(u, c, name, message, mode, error); + r = bus_cgroup_set_transient_property(u, c, name, message, flags, error); if (r != 0) return r; |