|
|
4cad4c |
From f45cb6d6a2c247c7594d9965cbb745303adb61d6 Mon Sep 17 00:00:00 2001
|
|
|
4cad4c |
From: Chris Down <chris@chrisdown.name>
|
|
|
4cad4c |
Date: Thu, 28 Mar 2019 12:50:50 +0000
|
|
|
4cad4c |
Subject: [PATCH] cgroup: Implement default propagation of MemoryLow with
|
|
|
4cad4c |
DefaultMemoryLow
|
|
|
4cad4c |
|
|
|
4cad4c |
In cgroup v2 we have protection tunables -- currently MemoryLow and
|
|
|
4cad4c |
MemoryMin (there will be more in future for other resources, too). The
|
|
|
4cad4c |
design of these protection tunables requires not only intermediate
|
|
|
4cad4c |
cgroups to propagate protections, but also the units at the leaf of that
|
|
|
4cad4c |
resource's operation to accept it (by setting MemoryLow or MemoryMin).
|
|
|
4cad4c |
|
|
|
4cad4c |
This makes sense from an low-level API design perspective, but it's a
|
|
|
4cad4c |
good idea to also have a higher-level abstraction that can, by default,
|
|
|
4cad4c |
propagate these resources to children recursively. In this patch, this
|
|
|
4cad4c |
happens by having descendants set memory.low to N if their ancestor has
|
|
|
4cad4c |
DefaultMemoryLow=N -- assuming they don't set a separate MemoryLow
|
|
|
4cad4c |
value.
|
|
|
4cad4c |
|
|
|
4cad4c |
Any affected unit can opt out of this propagation by manually setting
|
|
|
4cad4c |
`MemoryLow` to some value in its unit configuration. A unit can also
|
|
|
4cad4c |
stop further propagation by setting `DefaultMemoryLow=` with no
|
|
|
4cad4c |
argument. This removes further propagation in the subtree, but has no
|
|
|
4cad4c |
effect on the unit itself (for that, use `MemoryLow=0`).
|
|
|
4cad4c |
|
|
|
4cad4c |
Our use case in production is simplifying the configuration of machines
|
|
|
4cad4c |
which heavily rely on memory protection tunables, but currently require
|
|
|
4cad4c |
tweaking a huge number of unit files to make that a reality. This
|
|
|
4cad4c |
directive makes that significantly less fragile, and decreases the risk
|
|
|
4cad4c |
of misconfiguration.
|
|
|
4cad4c |
|
|
|
4cad4c |
After this patch is merged, I will implement DefaultMemoryMin= using the
|
|
|
4cad4c |
same principles.
|
|
|
4cad4c |
|
|
|
4cad4c |
(cherry picked from commit c52db42b78f6fbeb7792cc4eca27e2767a48b6ca)
|
|
|
4cad4c |
|
|
|
4cad4c |
Related: #1763435
|
|
|
4cad4c |
---
|
|
|
4cad4c |
doc/TRANSIENT-SETTINGS.md | 1 +
|
|
|
4cad4c |
man/systemd.resource-control.xml | 4 +
|
|
|
4cad4c |
src/core/cgroup.c | 58 +++++++++--
|
|
|
4cad4c |
src/core/cgroup.h | 6 ++
|
|
|
4cad4c |
src/core/dbus-cgroup.c | 7 ++
|
|
|
4cad4c |
src/core/load-fragment-gperf.gperf.m4 | 1 +
|
|
|
4cad4c |
src/core/load-fragment.c | 13 ++-
|
|
|
4cad4c |
src/shared/bus-unit-util.c | 2 +-
|
|
|
4cad4c |
src/shared/bus-util.c | 2 +-
|
|
|
4cad4c |
src/systemctl/systemctl.c | 3 +
|
|
|
4cad4c |
src/test/meson.build | 6 ++
|
|
|
4cad4c |
src/test/test-cgroup-unit-default.c | 145 ++++++++++++++++++++++++++
|
|
|
4cad4c |
test/dml-discard-empty.service | 7 ++
|
|
|
4cad4c |
test/dml-discard-set-ml.service | 8 ++
|
|
|
4cad4c |
test/dml-discard.slice | 5 +
|
|
|
4cad4c |
test/dml-override-empty.service | 7 ++
|
|
|
4cad4c |
test/dml-override.slice | 5 +
|
|
|
4cad4c |
test/dml-passthrough-empty.service | 7 ++
|
|
|
4cad4c |
test/dml-passthrough-set-dml.service | 8 ++
|
|
|
4cad4c |
test/dml-passthrough-set-ml.service | 8 ++
|
|
|
4cad4c |
test/dml-passthrough.slice | 5 +
|
|
|
4cad4c |
test/dml.slice | 5 +
|
|
|
4cad4c |
test/meson.build | 10 ++
|
|
|
4cad4c |
23 files changed, 310 insertions(+), 13 deletions(-)
|
|
|
4cad4c |
create mode 100644 src/test/test-cgroup-unit-default.c
|
|
|
4cad4c |
create mode 100644 test/dml-discard-empty.service
|
|
|
4cad4c |
create mode 100644 test/dml-discard-set-ml.service
|
|
|
4cad4c |
create mode 100644 test/dml-discard.slice
|
|
|
4cad4c |
create mode 100644 test/dml-override-empty.service
|
|
|
4cad4c |
create mode 100644 test/dml-override.slice
|
|
|
4cad4c |
create mode 100644 test/dml-passthrough-empty.service
|
|
|
4cad4c |
create mode 100644 test/dml-passthrough-set-dml.service
|
|
|
4cad4c |
create mode 100644 test/dml-passthrough-set-ml.service
|
|
|
4cad4c |
create mode 100644 test/dml-passthrough.slice
|
|
|
4cad4c |
create mode 100644 test/dml.slice
|
|
|
4cad4c |
|
|
|
4cad4c |
diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md
|
|
|
4cad4c |
index 93865c0333..5a8fa0727e 100644
|
|
|
4cad4c |
--- a/doc/TRANSIENT-SETTINGS.md
|
|
|
4cad4c |
+++ b/doc/TRANSIENT-SETTINGS.md
|
|
|
4cad4c |
@@ -223,6 +223,7 @@ All cgroup/resource control settings are available for transient units
|
|
|
4cad4c |
✓ AllowedMemoryNodes=
|
|
|
4cad4c |
✓ MemoryAccounting=
|
|
|
4cad4c |
✓ MemoryMin=
|
|
|
4cad4c |
+✓ DefaultMemoryLow=
|
|
|
4cad4c |
✓ MemoryLow=
|
|
|
4cad4c |
✓ MemoryHigh=
|
|
|
4cad4c |
✓ MemoryMax=
|
|
|
4cad4c |
diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml
|
|
|
4cad4c |
index 63a0c87565..27f16001dd 100644
|
|
|
4cad4c |
--- a/man/systemd.resource-control.xml
|
|
|
4cad4c |
+++ b/man/systemd.resource-control.xml
|
|
|
4cad4c |
@@ -305,6 +305,10 @@
|
|
|
4cad4c |
|
|
|
4cad4c |
<para>This setting is supported only if the unified control group hierarchy is used and disables
|
|
|
4cad4c |
<varname>MemoryLimit=</varname>.</para>
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ <para>Units may can have their children use a default <literal>memory.low</literal> value by specifying
|
|
|
4cad4c |
+ <varname>DefaultMemoryLow=</varname>, which has the same usage as <varname>MemoryLow=</varname>. This setting
|
|
|
4cad4c |
+ does not affect <literal>memory.low</literal> in the unit itself.</para>
|
|
|
4cad4c |
</listitem>
|
|
|
4cad4c |
</varlistentry>
|
|
|
4cad4c |
|
|
|
4cad4c |
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
|
|
|
4cad4c |
index a17b38f914..f804bf4727 100644
|
|
|
4cad4c |
--- a/src/core/cgroup.c
|
|
|
4cad4c |
+++ b/src/core/cgroup.c
|
|
|
4cad4c |
@@ -220,6 +220,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
|
|
|
4cad4c |
"%sStartupIOWeight=%" PRIu64 "\n"
|
|
|
4cad4c |
"%sBlockIOWeight=%" PRIu64 "\n"
|
|
|
4cad4c |
"%sStartupBlockIOWeight=%" PRIu64 "\n"
|
|
|
4cad4c |
+ "%sDefaultMemoryLow=%" PRIu64 "\n"
|
|
|
4cad4c |
"%sMemoryMin=%" PRIu64 "\n"
|
|
|
4cad4c |
"%sMemoryLow=%" PRIu64 "\n"
|
|
|
4cad4c |
"%sMemoryHigh=%" PRIu64 "\n"
|
|
|
4cad4c |
@@ -247,6 +248,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
|
|
|
4cad4c |
prefix, c->startup_io_weight,
|
|
|
4cad4c |
prefix, c->blockio_weight,
|
|
|
4cad4c |
prefix, c->startup_blockio_weight,
|
|
|
4cad4c |
+ prefix, c->default_memory_low,
|
|
|
4cad4c |
prefix, c->memory_min,
|
|
|
4cad4c |
prefix, c->memory_low,
|
|
|
4cad4c |
prefix, c->memory_high,
|
|
|
4cad4c |
@@ -370,6 +372,32 @@ int cgroup_add_device_allow(CGroupContext *c, const char *dev, const char *mode)
|
|
|
4cad4c |
return 0;
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
+uint64_t unit_get_ancestor_memory_low(Unit *u) {
|
|
|
4cad4c |
+ CGroupContext *c;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ /* 1. Is MemoryLow set in this unit? If so, use that.
|
|
|
4cad4c |
+ * 2. Is DefaultMemoryLow set in any ancestor? If so, use that.
|
|
|
4cad4c |
+ * 3. Otherwise, return CGROUP_LIMIT_MIN. */
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert(u);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ c = unit_get_cgroup_context(u);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ if (c->memory_low_set)
|
|
|
4cad4c |
+ return c->memory_low;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ while (UNIT_ISSET(u->slice)) {
|
|
|
4cad4c |
+ u = UNIT_DEREF(u->slice);
|
|
|
4cad4c |
+ c = unit_get_cgroup_context(u);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ if (c->default_memory_low_set)
|
|
|
4cad4c |
+ return c->default_memory_low;
|
|
|
4cad4c |
+ }
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ /* We've reached the root, but nobody had DefaultMemoryLow set, so set it to the kernel default. */
|
|
|
4cad4c |
+ return CGROUP_LIMIT_MIN;
|
|
|
4cad4c |
+}
|
|
|
4cad4c |
+
|
|
|
4cad4c |
static int lookup_block_device(const char *p, dev_t *ret) {
|
|
|
4cad4c |
struct stat st;
|
|
|
4cad4c |
int r;
|
|
|
4cad4c |
@@ -807,8 +835,17 @@ static void cgroup_apply_blkio_device_limit(Unit *u, const char *dev_path, uint6
|
|
|
4cad4c |
"Failed to set blkio.throttle.write_bps_device: %m");
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
-static bool cgroup_context_has_unified_memory_config(CGroupContext *c) {
|
|
|
4cad4c |
- return c->memory_min > 0 || c->memory_low > 0 || c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX || c->memory_swap_max != CGROUP_LIMIT_MAX;
|
|
|
4cad4c |
+static bool unit_has_unified_memory_config(Unit *u) {
|
|
|
4cad4c |
+ CGroupContext *c;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert(u);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ c = unit_get_cgroup_context(u);
|
|
|
4cad4c |
+ assert(c);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ return c->memory_min > 0 || unit_get_ancestor_memory_low(u) > 0 ||
|
|
|
4cad4c |
+ c->memory_high != CGROUP_LIMIT_MAX || c->memory_max != CGROUP_LIMIT_MAX ||
|
|
|
4cad4c |
+ c->memory_swap_max != CGROUP_LIMIT_MAX;
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
static void cgroup_apply_unified_memory_limit(Unit *u, const char *file, uint64_t v) {
|
|
|
4cad4c |
@@ -1056,7 +1093,7 @@ static void cgroup_context_apply(
|
|
|
4cad4c |
if (cg_all_unified() > 0) {
|
|
|
4cad4c |
uint64_t max, swap_max = CGROUP_LIMIT_MAX;
|
|
|
4cad4c |
|
|
|
4cad4c |
- if (cgroup_context_has_unified_memory_config(c)) {
|
|
|
4cad4c |
+ if (unit_has_unified_memory_config(u)) {
|
|
|
4cad4c |
max = c->memory_max;
|
|
|
4cad4c |
swap_max = c->memory_swap_max;
|
|
|
4cad4c |
} else {
|
|
|
4cad4c |
@@ -1067,7 +1104,7 @@ static void cgroup_context_apply(
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
cgroup_apply_unified_memory_limit(u, "memory.min", c->memory_min);
|
|
|
4cad4c |
- cgroup_apply_unified_memory_limit(u, "memory.low", c->memory_low);
|
|
|
4cad4c |
+ cgroup_apply_unified_memory_limit(u, "memory.low", unit_get_ancestor_memory_low(u));
|
|
|
4cad4c |
cgroup_apply_unified_memory_limit(u, "memory.high", c->memory_high);
|
|
|
4cad4c |
cgroup_apply_unified_memory_limit(u, "memory.max", max);
|
|
|
4cad4c |
cgroup_apply_unified_memory_limit(u, "memory.swap.max", swap_max);
|
|
|
4cad4c |
@@ -1075,7 +1112,7 @@ static void cgroup_context_apply(
|
|
|
4cad4c |
char buf[DECIMAL_STR_MAX(uint64_t) + 1];
|
|
|
4cad4c |
uint64_t val;
|
|
|
4cad4c |
|
|
|
4cad4c |
- if (cgroup_context_has_unified_memory_config(c)) {
|
|
|
4cad4c |
+ if (unit_has_unified_memory_config(u)) {
|
|
|
4cad4c |
val = c->memory_max;
|
|
|
4cad4c |
log_cgroup_compat(u, "Applying MemoryMax %" PRIi64 " as MemoryLimit", val);
|
|
|
4cad4c |
} else
|
|
|
4cad4c |
@@ -1204,8 +1241,13 @@ static void cgroup_context_apply(
|
|
|
4cad4c |
cgroup_apply_firewall(u);
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
-CGroupMask cgroup_context_get_mask(CGroupContext *c) {
|
|
|
4cad4c |
+static CGroupMask unit_get_cgroup_mask(Unit *u) {
|
|
|
4cad4c |
CGroupMask mask = 0;
|
|
|
4cad4c |
+ CGroupContext *c;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert(u);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ c = unit_get_cgroup_context(u);
|
|
|
4cad4c |
|
|
|
4cad4c |
/* Figure out which controllers we need */
|
|
|
4cad4c |
|
|
|
4cad4c |
@@ -1223,7 +1265,7 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) {
|
|
|
4cad4c |
|
|
|
4cad4c |
if (c->memory_accounting ||
|
|
|
4cad4c |
c->memory_limit != CGROUP_LIMIT_MAX ||
|
|
|
4cad4c |
- cgroup_context_has_unified_memory_config(c))
|
|
|
4cad4c |
+ unit_has_unified_memory_config(u))
|
|
|
4cad4c |
mask |= CGROUP_MASK_MEMORY;
|
|
|
4cad4c |
|
|
|
4cad4c |
if (c->device_allow ||
|
|
|
4cad4c |
@@ -1246,7 +1288,7 @@ CGroupMask unit_get_own_mask(Unit *u) {
|
|
|
4cad4c |
if (!c)
|
|
|
4cad4c |
return 0;
|
|
|
4cad4c |
|
|
|
4cad4c |
- return cgroup_context_get_mask(c) | unit_get_delegate_mask(u);
|
|
|
4cad4c |
+ return unit_get_cgroup_mask(u) | unit_get_delegate_mask(u);
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
CGroupMask unit_get_delegate_mask(Unit *u) {
|
|
|
4cad4c |
diff --git a/src/core/cgroup.h b/src/core/cgroup.h
|
|
|
4cad4c |
index 8102b442b8..a263d6a169 100644
|
|
|
4cad4c |
--- a/src/core/cgroup.h
|
|
|
4cad4c |
+++ b/src/core/cgroup.h
|
|
|
4cad4c |
@@ -95,12 +95,16 @@ struct CGroupContext {
|
|
|
4cad4c |
LIST_HEAD(CGroupIODeviceLimit, io_device_limits);
|
|
|
4cad4c |
LIST_HEAD(CGroupIODeviceLatency, io_device_latencies);
|
|
|
4cad4c |
|
|
|
4cad4c |
+ uint64_t default_memory_low;
|
|
|
4cad4c |
uint64_t memory_min;
|
|
|
4cad4c |
uint64_t memory_low;
|
|
|
4cad4c |
uint64_t memory_high;
|
|
|
4cad4c |
uint64_t memory_max;
|
|
|
4cad4c |
uint64_t memory_swap_max;
|
|
|
4cad4c |
|
|
|
4cad4c |
+ bool default_memory_low_set;
|
|
|
4cad4c |
+ bool memory_low_set;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
LIST_HEAD(IPAddressAccessItem, ip_address_allow);
|
|
|
4cad4c |
LIST_HEAD(IPAddressAccessItem, ip_address_deny);
|
|
|
4cad4c |
|
|
|
4cad4c |
@@ -191,6 +195,8 @@ Unit *manager_get_unit_by_cgroup(Manager *m, const char *cgroup);
|
|
|
4cad4c |
Unit *manager_get_unit_by_pid_cgroup(Manager *m, pid_t pid);
|
|
|
4cad4c |
Unit* manager_get_unit_by_pid(Manager *m, pid_t pid);
|
|
|
4cad4c |
|
|
|
4cad4c |
+uint64_t unit_get_ancestor_memory_low(Unit *u);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
int unit_search_main_pid(Unit *u, pid_t *ret);
|
|
|
4cad4c |
int unit_watch_all_pids(Unit *u);
|
|
|
4cad4c |
|
|
|
4cad4c |
diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
|
|
|
4cad4c |
index 6ce5984a02..2115d43b0c 100644
|
|
|
4cad4c |
--- a/src/core/dbus-cgroup.c
|
|
|
4cad4c |
+++ b/src/core/dbus-cgroup.c
|
|
|
4cad4c |
@@ -353,6 +353,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
|
|
|
4cad4c |
SD_BUS_PROPERTY("BlockIOReadBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
|
|
|
4cad4c |
SD_BUS_PROPERTY("BlockIOWriteBandwidth", "a(st)", property_get_blockio_device_bandwidths, 0, 0),
|
|
|
4cad4c |
SD_BUS_PROPERTY("MemoryAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, memory_accounting), 0),
|
|
|
4cad4c |
+ SD_BUS_PROPERTY("DefaultMemoryLow", "t", NULL, offsetof(CGroupContext, default_memory_low), 0),
|
|
|
4cad4c |
SD_BUS_PROPERTY("MemoryMin", "t", NULL, offsetof(CGroupContext, memory_min), 0),
|
|
|
4cad4c |
SD_BUS_PROPERTY("MemoryLow", "t", NULL, offsetof(CGroupContext, memory_low), 0),
|
|
|
4cad4c |
SD_BUS_PROPERTY("MemoryHigh", "t", NULL, offsetof(CGroupContext, memory_high), 0),
|
|
|
4cad4c |
@@ -668,6 +669,9 @@ int bus_cgroup_set_property(
|
|
|
4cad4c |
if (streq(name, "MemoryLow"))
|
|
|
4cad4c |
return bus_cgroup_set_memory(u, name, &c->memory_low, message, flags, error);
|
|
|
4cad4c |
|
|
|
4cad4c |
+ if (streq(name, "DefaultMemoryLow"))
|
|
|
4cad4c |
+ return bus_cgroup_set_memory(u, name, &c->default_memory_low, message, flags, error);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
if (streq(name, "MemoryHigh"))
|
|
|
4cad4c |
return bus_cgroup_set_memory(u, name, &c->memory_high, message, flags, error);
|
|
|
4cad4c |
|
|
|
4cad4c |
@@ -686,6 +690,9 @@ int bus_cgroup_set_property(
|
|
|
4cad4c |
if (streq(name, "MemoryLowScale"))
|
|
|
4cad4c |
return bus_cgroup_set_memory_scale(u, name, &c->memory_low, message, flags, error);
|
|
|
4cad4c |
|
|
|
4cad4c |
+ if (streq(name, "DefaultMemoryLowScale"))
|
|
|
4cad4c |
+ return bus_cgroup_set_memory_scale(u, name, &c->default_memory_low, message, flags, error);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
if (streq(name, "MemoryHighScale"))
|
|
|
4cad4c |
return bus_cgroup_set_memory_scale(u, name, &c->memory_high, message, flags, error);
|
|
|
4cad4c |
|
|
|
4cad4c |
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
|
|
|
4cad4c |
index 1c6e539f30..43cc78fdea 100644
|
|
|
4cad4c |
--- a/src/core/load-fragment-gperf.gperf.m4
|
|
|
4cad4c |
+++ b/src/core/load-fragment-gperf.gperf.m4
|
|
|
4cad4c |
@@ -172,6 +172,7 @@ $1.CPUQuota, config_parse_cpu_quota, 0,
|
|
|
4cad4c |
$1.CPUQuotaPeriodSec, config_parse_sec_def_infinity, 0, offsetof($1, cgroup_context.cpu_quota_period_usec)
|
|
|
4cad4c |
$1.MemoryAccounting, config_parse_bool, 0, offsetof($1, cgroup_context.memory_accounting)
|
|
|
4cad4c |
$1.MemoryMin, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
|
|
4cad4c |
+$1.DefaultMemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
|
|
4cad4c |
$1.MemoryLow, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
|
|
4cad4c |
$1.MemoryHigh, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
|
|
4cad4c |
$1.MemoryMax, config_parse_memory_limit, 0, offsetof($1, cgroup_context)
|
|
|
4cad4c |
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
|
|
|
4cad4c |
index 89a3457acc..20faed02ad 100644
|
|
|
4cad4c |
--- a/src/core/load-fragment.c
|
|
|
4cad4c |
+++ b/src/core/load-fragment.c
|
|
|
4cad4c |
@@ -3096,11 +3096,18 @@ int config_parse_memory_limit(
|
|
|
4cad4c |
}
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
- if (streq(lvalue, "MemoryMin"))
|
|
|
4cad4c |
+ if (streq(lvalue, "DefaultMemoryLow")) {
|
|
|
4cad4c |
+ c->default_memory_low_set = true;
|
|
|
4cad4c |
+ if (isempty(rvalue))
|
|
|
4cad4c |
+ c->default_memory_low = CGROUP_LIMIT_MIN;
|
|
|
4cad4c |
+ else
|
|
|
4cad4c |
+ c->default_memory_low = bytes;
|
|
|
4cad4c |
+ } else if (streq(lvalue, "MemoryMin"))
|
|
|
4cad4c |
c->memory_min = bytes;
|
|
|
4cad4c |
- else if (streq(lvalue, "MemoryLow"))
|
|
|
4cad4c |
+ else if (streq(lvalue, "MemoryLow")) {
|
|
|
4cad4c |
c->memory_low = bytes;
|
|
|
4cad4c |
- else if (streq(lvalue, "MemoryHigh"))
|
|
|
4cad4c |
+ c->memory_low_set = true;
|
|
|
4cad4c |
+ } else if (streq(lvalue, "MemoryHigh"))
|
|
|
4cad4c |
c->memory_high = bytes;
|
|
|
4cad4c |
else if (streq(lvalue, "MemoryMax"))
|
|
|
4cad4c |
c->memory_max = bytes;
|
|
|
4cad4c |
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
|
|
|
4cad4c |
index 203c068d02..f88730a85d 100644
|
|
|
4cad4c |
--- a/src/shared/bus-unit-util.c
|
|
|
4cad4c |
+++ b/src/shared/bus-unit-util.c
|
|
|
4cad4c |
@@ -429,7 +429,7 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons
|
|
|
4cad4c |
return 1;
|
|
|
4cad4c |
}
|
|
|
4cad4c |
|
|
|
4cad4c |
- if (STR_IN_SET(field, "MemoryMin", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) {
|
|
|
4cad4c |
+ if (STR_IN_SET(field, "MemoryMin", "DefaultMemoryLow", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit", "TasksMax")) {
|
|
|
4cad4c |
|
|
|
4cad4c |
if (isempty(eq) || streq(eq, "infinity")) {
|
|
|
4cad4c |
r = sd_bus_message_append(m, "(sv)", field, "t", CGROUP_LIMIT_MAX);
|
|
|
4cad4c |
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
|
|
|
4cad4c |
index 5ed68429be..0ba2712deb 100644
|
|
|
4cad4c |
--- a/src/shared/bus-util.c
|
|
|
4cad4c |
+++ b/src/shared/bus-util.c
|
|
|
4cad4c |
@@ -774,7 +774,7 @@ int bus_print_property(const char *name, sd_bus_message *m, bool value, bool all
|
|
|
4cad4c |
|
|
|
4cad4c |
print_property(name, "%s", "[not set]");
|
|
|
4cad4c |
|
|
|
4cad4c |
- else if ((STR_IN_SET(name, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) ||
|
|
|
4cad4c |
+ else if ((STR_IN_SET(name, "DefaultMemoryLow", "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) ||
|
|
|
4cad4c |
(STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) ||
|
|
|
4cad4c |
(startswith(name, "Limit") && u == (uint64_t) -1) ||
|
|
|
4cad4c |
(startswith(name, "DefaultLimit") && u == (uint64_t) -1))
|
|
|
4cad4c |
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
|
|
4cad4c |
index 35ad20f510..763ca0c6b7 100644
|
|
|
4cad4c |
--- a/src/systemctl/systemctl.c
|
|
|
4cad4c |
+++ b/src/systemctl/systemctl.c
|
|
|
4cad4c |
@@ -3918,6 +3918,8 @@ typedef struct UnitStatusInfo {
|
|
|
4cad4c |
uint64_t ip_ingress_bytes;
|
|
|
4cad4c |
uint64_t ip_egress_bytes;
|
|
|
4cad4c |
|
|
|
4cad4c |
+ uint64_t default_memory_low;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
LIST_HEAD(ExecStatusInfo, exec);
|
|
|
4cad4c |
} UnitStatusInfo;
|
|
|
4cad4c |
|
|
|
4cad4c |
@@ -5028,6 +5030,7 @@ static int show_one(
|
|
|
4cad4c |
{ "Where", "s", NULL, offsetof(UnitStatusInfo, where) },
|
|
|
4cad4c |
{ "What", "s", NULL, offsetof(UnitStatusInfo, what) },
|
|
|
4cad4c |
{ "MemoryCurrent", "t", NULL, offsetof(UnitStatusInfo, memory_current) },
|
|
|
4cad4c |
+ { "DefaultMemoryLow", "t", NULL, offsetof(UnitStatusInfo, default_memory_low) },
|
|
|
4cad4c |
{ "MemoryMin", "t", NULL, offsetof(UnitStatusInfo, memory_min) },
|
|
|
4cad4c |
{ "MemoryLow", "t", NULL, offsetof(UnitStatusInfo, memory_low) },
|
|
|
4cad4c |
{ "MemoryHigh", "t", NULL, offsetof(UnitStatusInfo, memory_high) },
|
|
|
4cad4c |
diff --git a/src/test/meson.build b/src/test/meson.build
|
|
|
4cad4c |
index 22264d034c..7b310d4ec7 100644
|
|
|
4cad4c |
--- a/src/test/meson.build
|
|
|
4cad4c |
+++ b/src/test/meson.build
|
|
|
4cad4c |
@@ -518,6 +518,12 @@ tests += [
|
|
|
4cad4c |
libshared],
|
|
|
4cad4c |
[]],
|
|
|
4cad4c |
|
|
|
4cad4c |
+ [['src/test/test-cgroup-unit-default.c',
|
|
|
4cad4c |
+ 'src/test/test-helper.c'],
|
|
|
4cad4c |
+ [libcore,
|
|
|
4cad4c |
+ libshared],
|
|
|
4cad4c |
+ []],
|
|
|
4cad4c |
+
|
|
|
4cad4c |
[['src/test/test-cgroup-mask.c',
|
|
|
4cad4c |
'src/test/test-helper.c'],
|
|
|
4cad4c |
[libcore,
|
|
|
4cad4c |
diff --git a/src/test/test-cgroup-unit-default.c b/src/test/test-cgroup-unit-default.c
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..54f7d50c45
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/src/test/test-cgroup-unit-default.c
|
|
|
4cad4c |
@@ -0,0 +1,145 @@
|
|
|
4cad4c |
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+#include <stdio.h>
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+#include "cgroup.h"
|
|
|
4cad4c |
+#include "manager.h"
|
|
|
4cad4c |
+#include "rm-rf.h"
|
|
|
4cad4c |
+#include "test-helper.h"
|
|
|
4cad4c |
+#include "tests.h"
|
|
|
4cad4c |
+#include "unit.h"
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+static int test_default_memory_low(void) {
|
|
|
4cad4c |
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
|
|
|
4cad4c |
+ _cleanup_(manager_freep) Manager *m = NULL;
|
|
|
4cad4c |
+ Unit *root, *dml,
|
|
|
4cad4c |
+ *dml_passthrough, *dml_passthrough_empty, *dml_passthrough_set_dml, *dml_passthrough_set_ml,
|
|
|
4cad4c |
+ *dml_override, *dml_override_empty,
|
|
|
4cad4c |
+ *dml_discard, *dml_discard_empty, *dml_discard_set_ml;
|
|
|
4cad4c |
+ uint64_t dml_tree_default;
|
|
|
4cad4c |
+ int r;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ r = enter_cgroup_subroot();
|
|
|
4cad4c |
+ if (r == -ENOMEDIUM)
|
|
|
4cad4c |
+ return EXIT_TEST_SKIP;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(set_unit_path(get_testdata_dir()) >= 0);
|
|
|
4cad4c |
+ assert_se(runtime_dir = setup_fake_runtime_dir());
|
|
|
4cad4c |
+ r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
|
|
|
4cad4c |
+ if (IN_SET(r, -EPERM, -EACCES)) {
|
|
|
4cad4c |
+ log_error_errno(r, "manager_new: %m");
|
|
|
4cad4c |
+ return EXIT_TEST_SKIP;
|
|
|
4cad4c |
+ }
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(r >= 0);
|
|
|
4cad4c |
+ assert_se(manager_startup(m, NULL, NULL) >= 0);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ /* dml.slice has DefaultMemoryLow=50. Beyond that, individual subhierarchies look like this:
|
|
|
4cad4c |
+ *
|
|
|
4cad4c |
+ * 1. dml-passthrough.slice sets MemoryLow=100. This should not affect its children, as only
|
|
|
4cad4c |
+ * DefaultMemoryLow is propagated, not MemoryLow. As such, all leaf services should end up with
|
|
|
4cad4c |
+ * memory.low as 50, inherited from dml.slice, *except* for dml-passthrough-set-ml.service, which
|
|
|
4cad4c |
+ * should have the value of 25, as it has MemoryLow explicitly set.
|
|
|
4cad4c |
+ *
|
|
|
4cad4c |
+ * ┌───────────┐
|
|
|
4cad4c |
+ * │ dml.slice │
|
|
|
4cad4c |
+ * └─────┬─────┘
|
|
|
4cad4c |
+ * MemoryLow=100
|
|
|
4cad4c |
+ * ┌───────────┴───────────┐
|
|
|
4cad4c |
+ * │ dml-passthrough.slice │
|
|
|
4cad4c |
+ * └───────────┬───────────┘
|
|
|
4cad4c |
+ * ┌───────────────────────────────────┼───────────────────────────────────┐
|
|
|
4cad4c |
+ * no new settings DefaultMemoryLow=15 MemoryLow=25
|
|
|
4cad4c |
+ * ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐
|
|
|
4cad4c |
+ * │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │
|
|
|
4cad4c |
+ * └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘
|
|
|
4cad4c |
+ *
|
|
|
4cad4c |
+ * 2. dml-override.slice sets DefaultMemoryLow=10. As such, dml-override-empty.service should also
|
|
|
4cad4c |
+ * end up with a memory.low of 10. dml-override.slice should still have a memory.low of 50.
|
|
|
4cad4c |
+ *
|
|
|
4cad4c |
+ * ┌───────────┐
|
|
|
4cad4c |
+ * │ dml.slice │
|
|
|
4cad4c |
+ * └─────┬─────┘
|
|
|
4cad4c |
+ * DefaultMemoryLow=10
|
|
|
4cad4c |
+ * ┌─────────┴──────────┐
|
|
|
4cad4c |
+ * │ dml-override.slice │
|
|
|
4cad4c |
+ * └─────────┬──────────┘
|
|
|
4cad4c |
+ * no new settings
|
|
|
4cad4c |
+ * ┌─────────────┴──────────────┐
|
|
|
4cad4c |
+ * │ dml-override-empty.service │
|
|
|
4cad4c |
+ * └────────────────────────────┘
|
|
|
4cad4c |
+ *
|
|
|
4cad4c |
+ * 3. dml-discard.slice sets DefaultMemoryLow= with no rvalue. As such,
|
|
|
4cad4c |
+ * dml-discard-empty.service should end up with a value of 0.
|
|
|
4cad4c |
+ * dml-discard-explicit-ml.service sets MemoryLow=70, and as such should have that override the
|
|
|
4cad4c |
+ * reset DefaultMemoryLow value. dml-discard.slice should still have an eventual memory.low of 50.
|
|
|
4cad4c |
+ *
|
|
|
4cad4c |
+ * ┌───────────┐
|
|
|
4cad4c |
+ * │ dml.slice │
|
|
|
4cad4c |
+ * └─────┬─────┘
|
|
|
4cad4c |
+ * DefaultMemoryLow=
|
|
|
4cad4c |
+ * ┌─────────┴─────────┐
|
|
|
4cad4c |
+ * │ dml-discard.slice │
|
|
|
4cad4c |
+ * └─────────┬─────────┘
|
|
|
4cad4c |
+ * ┌──────────────┴───────────────┐
|
|
|
4cad4c |
+ * no new settings MemoryLow=15
|
|
|
4cad4c |
+ * ┌─────────────┴─────────────┐ ┌─────────────┴──────────────┐
|
|
|
4cad4c |
+ * │ dml-discard-empty.service │ │ dml-discard-set-ml.service │
|
|
|
4cad4c |
+ * └───────────────────────────┘ └────────────────────────────┘
|
|
|
4cad4c |
+ */
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml.slice", NULL, &dml) >= 0);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough.slice", NULL, &dml_passthrough) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_passthrough->slice) == dml);
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-empty.service", NULL, &dml_passthrough_empty) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_passthrough_empty->slice) == dml_passthrough);
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-dml.service", NULL, &dml_passthrough_set_dml) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_passthrough_set_dml->slice) == dml_passthrough);
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-ml.service", NULL, &dml_passthrough_set_ml) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_passthrough_set_ml->slice) == dml_passthrough);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-override.slice", NULL, &dml_override) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_override->slice) == dml);
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-override-empty.service", NULL, &dml_override_empty) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_override_empty->slice) == dml_override);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-discard.slice", NULL, &dml_discard) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_discard->slice) == dml);
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-discard-empty.service", NULL, &dml_discard_empty) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_discard_empty->slice) == dml_discard);
|
|
|
4cad4c |
+ assert_se(manager_load_startable_unit_or_warn(m, "dml-discard-set-ml.service", NULL, &dml_discard_set_ml) >= 0);
|
|
|
4cad4c |
+ assert_se(UNIT_DEREF(dml_discard_set_ml->slice) == dml_discard);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ root = UNIT_DEREF(dml->slice);
|
|
|
4cad4c |
+ assert_se(!UNIT_ISSET(root->slice));
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(root) == CGROUP_LIMIT_MIN);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml) == CGROUP_LIMIT_MIN);
|
|
|
4cad4c |
+ dml_tree_default = unit_get_cgroup_context(dml)->default_memory_low;
|
|
|
4cad4c |
+ assert_se(dml_tree_default == 50);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_passthrough) == 100);
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_passthrough_empty) == dml_tree_default);
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_dml) == 50);
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 25);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_override) == dml_tree_default);
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_override_empty) == 10);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_discard) == dml_tree_default);
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_discard_empty) == CGROUP_LIMIT_MIN);
|
|
|
4cad4c |
+ assert_se(unit_get_ancestor_memory_low(dml_discard_set_ml) == 15);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ return 0;
|
|
|
4cad4c |
+}
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+int main(int argc, char* argv[]) {
|
|
|
4cad4c |
+ int rc = EXIT_SUCCESS;
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ test_setup_logging(LOG_DEBUG);
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ TEST_REQ_RUNNING_SYSTEMD(rc = test_default_memory_low());
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+ return rc;
|
|
|
4cad4c |
+}
|
|
|
4cad4c |
diff --git a/test/dml-discard-empty.service b/test/dml-discard-empty.service
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..75228f6470
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-discard-empty.service
|
|
|
4cad4c |
@@ -0,0 +1,7 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML discard empty service
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Service]
|
|
|
4cad4c |
+Slice=dml-discard.slice
|
|
|
4cad4c |
+Type=oneshot
|
|
|
4cad4c |
+ExecStart=/bin/true
|
|
|
4cad4c |
diff --git a/test/dml-discard-set-ml.service b/test/dml-discard-set-ml.service
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..591c99270c
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-discard-set-ml.service
|
|
|
4cad4c |
@@ -0,0 +1,8 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML discard set ml service
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Service]
|
|
|
4cad4c |
+Slice=dml-discard.slice
|
|
|
4cad4c |
+Type=oneshot
|
|
|
4cad4c |
+ExecStart=/bin/true
|
|
|
4cad4c |
+MemoryLow=15
|
|
|
4cad4c |
diff --git a/test/dml-discard.slice b/test/dml-discard.slice
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..e26d86846c
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-discard.slice
|
|
|
4cad4c |
@@ -0,0 +1,5 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML discard slice
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Slice]
|
|
|
4cad4c |
+DefaultMemoryLow=
|
|
|
4cad4c |
diff --git a/test/dml-override-empty.service b/test/dml-override-empty.service
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..142c98720c
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-override-empty.service
|
|
|
4cad4c |
@@ -0,0 +1,7 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML override empty service
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Service]
|
|
|
4cad4c |
+Slice=dml-override.slice
|
|
|
4cad4c |
+Type=oneshot
|
|
|
4cad4c |
+ExecStart=/bin/true
|
|
|
4cad4c |
diff --git a/test/dml-override.slice b/test/dml-override.slice
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..feb6773e39
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-override.slice
|
|
|
4cad4c |
@@ -0,0 +1,5 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML override slice
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Slice]
|
|
|
4cad4c |
+DefaultMemoryLow=10
|
|
|
4cad4c |
diff --git a/test/dml-passthrough-empty.service b/test/dml-passthrough-empty.service
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..34832de491
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-passthrough-empty.service
|
|
|
4cad4c |
@@ -0,0 +1,7 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML passthrough empty service
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Service]
|
|
|
4cad4c |
+Slice=dml-passthrough.slice
|
|
|
4cad4c |
+Type=oneshot
|
|
|
4cad4c |
+ExecStart=/bin/true
|
|
|
4cad4c |
diff --git a/test/dml-passthrough-set-dml.service b/test/dml-passthrough-set-dml.service
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..5bdf4ed4b7
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-passthrough-set-dml.service
|
|
|
4cad4c |
@@ -0,0 +1,8 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML passthrough set DML service
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Service]
|
|
|
4cad4c |
+Slice=dml-passthrough.slice
|
|
|
4cad4c |
+Type=oneshot
|
|
|
4cad4c |
+ExecStart=/bin/true
|
|
|
4cad4c |
+DefaultMemoryLow=15
|
|
|
4cad4c |
diff --git a/test/dml-passthrough-set-ml.service b/test/dml-passthrough-set-ml.service
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..2abd591389
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-passthrough-set-ml.service
|
|
|
4cad4c |
@@ -0,0 +1,8 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML passthrough set ML service
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Service]
|
|
|
4cad4c |
+Slice=dml-passthrough.slice
|
|
|
4cad4c |
+Type=oneshot
|
|
|
4cad4c |
+ExecStart=/bin/true
|
|
|
4cad4c |
+MemoryLow=25
|
|
|
4cad4c |
diff --git a/test/dml-passthrough.slice b/test/dml-passthrough.slice
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..1b1a848edb
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml-passthrough.slice
|
|
|
4cad4c |
@@ -0,0 +1,5 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML passthrough slice
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Slice]
|
|
|
4cad4c |
+MemoryLow=100
|
|
|
4cad4c |
diff --git a/test/dml.slice b/test/dml.slice
|
|
|
4cad4c |
new file mode 100644
|
|
|
4cad4c |
index 0000000000..84e333ef04
|
|
|
4cad4c |
--- /dev/null
|
|
|
4cad4c |
+++ b/test/dml.slice
|
|
|
4cad4c |
@@ -0,0 +1,5 @@
|
|
|
4cad4c |
+[Unit]
|
|
|
4cad4c |
+Description=DML slice
|
|
|
4cad4c |
+
|
|
|
4cad4c |
+[Slice]
|
|
|
4cad4c |
+DefaultMemoryLow=50
|
|
|
4cad4c |
diff --git a/test/meson.build b/test/meson.build
|
|
|
4cad4c |
index 070731c4a9..52e4fa2e3c 100644
|
|
|
4cad4c |
--- a/test/meson.build
|
|
|
4cad4c |
+++ b/test/meson.build
|
|
|
4cad4c |
@@ -7,6 +7,16 @@ test_data_files = '''
|
|
|
4cad4c |
c.service
|
|
|
4cad4c |
d.service
|
|
|
4cad4c |
daughter.service
|
|
|
4cad4c |
+ dml.slice
|
|
|
4cad4c |
+ dml-passthrough.slice
|
|
|
4cad4c |
+ dml-passthrough-empty.service
|
|
|
4cad4c |
+ dml-passthrough-set-dml.service
|
|
|
4cad4c |
+ dml-passthrough-set-ml.service
|
|
|
4cad4c |
+ dml-override.slice
|
|
|
4cad4c |
+ dml-override-empty.service
|
|
|
4cad4c |
+ dml-discard.slice
|
|
|
4cad4c |
+ dml-discard-empty.service
|
|
|
4cad4c |
+ dml-discard-set-ml.service
|
|
|
4cad4c |
e.service
|
|
|
4cad4c |
end.service
|
|
|
4cad4c |
f.service
|