]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-cgroup-unit-default.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
8 #include "test-helper.h"
12 static int test_default_memory_low(void) {
13 _cleanup_(rm_rf_physical_and_freep
) char *runtime_dir
= NULL
;
14 _cleanup_(manager_freep
) Manager
*m
= NULL
;
16 *dml_passthrough
, *dml_passthrough_empty
, *dml_passthrough_set_dml
, *dml_passthrough_set_ml
,
17 *dml_override
, *dml_override_empty
,
18 *dml_discard
, *dml_discard_empty
, *dml_discard_set_ml
;
19 uint64_t dml_tree_default
;
22 r
= enter_cgroup_subroot();
24 return log_tests_skipped("cgroupfs not available");
26 assert_se(set_unit_path(get_testdata_dir()) >= 0);
27 assert_se(runtime_dir
= setup_fake_runtime_dir());
28 r
= manager_new(UNIT_FILE_USER
, MANAGER_TEST_RUN_BASIC
, &m
);
29 if (IN_SET(r
, -EPERM
, -EACCES
)) {
30 log_error_errno(r
, "manager_new: %m");
31 return log_tests_skipped("cannot create manager");
35 assert_se(manager_startup(m
, NULL
, NULL
) >= 0);
37 /* dml.slice has DefaultMemoryLow=50. Beyond that, individual subhierarchies look like this:
39 * 1. dml-passthrough.slice sets MemoryLow=100. This should not affect its children, as only
40 * DefaultMemoryLow is propagated, not MemoryLow. As such, all leaf services should end up with
41 * memory.low as 50, inherited from dml.slice, *except* for dml-passthrough-set-ml.service, which
42 * should have the value of 0, as it has MemoryLow explicitly set.
48 * ┌───────────┴───────────┐
49 * │ dml-passthrough.slice │
50 * └───────────┬───────────┘
51 * ┌───────────────────────────────────┼───────────────────────────────────┐
52 * no new settings DefaultMemoryLow=15 MemoryLow=0
53 * ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐
54 * │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │
55 * └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘
57 * 2. dml-override.slice sets DefaultMemoryLow=10. As such, dml-override-empty.service should also
58 * end up with a memory.low of 10. dml-override.slice should still have a memory.low of 50.
64 * ┌─────────┴──────────┐
65 * │ dml-override.slice │
66 * └─────────┬──────────┘
68 * ┌─────────────┴──────────────┐
69 * │ dml-override-empty.service │
70 * └────────────────────────────┘
72 * 3. dml-discard.slice sets DefaultMemoryLow= with no rvalue. As such,
73 * dml-discard-empty.service should end up with a value of 0.
74 * dml-discard-explicit-ml.service sets MemoryLow=70, and as such should have that override the
75 * reset DefaultMemoryLow value. dml-discard.slice should still have an eventual memory.low of 50.
81 * ┌─────────┴─────────┐
82 * │ dml-discard.slice │
83 * └─────────┬─────────┘
84 * ┌──────────────┴───────────────┐
85 * no new settings MemoryLow=15
86 * ┌─────────────┴─────────────┐ ┌─────────────┴──────────────┐
87 * │ dml-discard-empty.service │ │ dml-discard-set-ml.service │
88 * └───────────────────────────┘ └────────────────────────────┘
90 assert_se(manager_load_startable_unit_or_warn(m
, "dml.slice", NULL
, &dml
) >= 0);
92 assert_se(manager_load_startable_unit_or_warn(m
, "dml-passthrough.slice", NULL
, &dml_passthrough
) >= 0);
93 assert_se(UNIT_DEREF(dml_passthrough
->slice
) == dml
);
94 assert_se(manager_load_startable_unit_or_warn(m
, "dml-passthrough-empty.service", NULL
, &dml_passthrough_empty
) >= 0);
95 assert_se(UNIT_DEREF(dml_passthrough_empty
->slice
) == dml_passthrough
);
96 assert_se(manager_load_startable_unit_or_warn(m
, "dml-passthrough-set-dml.service", NULL
, &dml_passthrough_set_dml
) >= 0);
97 assert_se(UNIT_DEREF(dml_passthrough_set_dml
->slice
) == dml_passthrough
);
98 assert_se(manager_load_startable_unit_or_warn(m
, "dml-passthrough-set-ml.service", NULL
, &dml_passthrough_set_ml
) >= 0);
99 assert_se(UNIT_DEREF(dml_passthrough_set_ml
->slice
) == dml_passthrough
);
101 assert_se(manager_load_startable_unit_or_warn(m
, "dml-override.slice", NULL
, &dml_override
) >= 0);
102 assert_se(UNIT_DEREF(dml_override
->slice
) == dml
);
103 assert_se(manager_load_startable_unit_or_warn(m
, "dml-override-empty.service", NULL
, &dml_override_empty
) >= 0);
104 assert_se(UNIT_DEREF(dml_override_empty
->slice
) == dml_override
);
106 assert_se(manager_load_startable_unit_or_warn(m
, "dml-discard.slice", NULL
, &dml_discard
) >= 0);
107 assert_se(UNIT_DEREF(dml_discard
->slice
) == dml
);
108 assert_se(manager_load_startable_unit_or_warn(m
, "dml-discard-empty.service", NULL
, &dml_discard_empty
) >= 0);
109 assert_se(UNIT_DEREF(dml_discard_empty
->slice
) == dml_discard
);
110 assert_se(manager_load_startable_unit_or_warn(m
, "dml-discard-set-ml.service", NULL
, &dml_discard_set_ml
) >= 0);
111 assert_se(UNIT_DEREF(dml_discard_set_ml
->slice
) == dml_discard
);
113 root
= UNIT_DEREF(dml
->slice
);
114 assert_se(!UNIT_ISSET(root
->slice
));
116 assert_se(unit_get_ancestor_memory_low(root
) == CGROUP_LIMIT_MIN
);
118 assert_se(unit_get_ancestor_memory_low(dml
) == CGROUP_LIMIT_MIN
);
119 dml_tree_default
= unit_get_cgroup_context(dml
)->default_memory_low
;
120 assert_se(dml_tree_default
== 50);
122 assert_se(unit_get_ancestor_memory_low(dml_passthrough
) == 100);
123 assert_se(unit_get_ancestor_memory_low(dml_passthrough_empty
) == dml_tree_default
);
124 assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_dml
) == 50);
125 assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml
) == 0);
127 assert_se(unit_get_ancestor_memory_low(dml_override
) == dml_tree_default
);
128 assert_se(unit_get_ancestor_memory_low(dml_override_empty
) == 10);
130 assert_se(unit_get_ancestor_memory_low(dml_discard
) == dml_tree_default
);
131 assert_se(unit_get_ancestor_memory_low(dml_discard_empty
) == CGROUP_LIMIT_MIN
);
132 assert_se(unit_get_ancestor_memory_low(dml_discard_set_ml
) == 15);
137 int main(int argc
, char* argv
[]) {
138 int rc
= EXIT_SUCCESS
;
140 test_setup_logging(LOG_DEBUG
);
142 TEST_REQ_RUNNING_SYSTEMD(rc
= test_default_memory_low());