summaryrefslogtreecommitdiff
path: root/src/core/dbus-cgroup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/dbus-cgroup.c')
-rw-r--r--src/core/dbus-cgroup.c356
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;