]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-cgroup-unit-default.c
Merge pull request #31648 from neighbourhoodie/review-content
[thirdparty/systemd.git] / src / test / test-cgroup-unit-default.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <stdio.h>
4
5 #include "cgroup.h"
6 #include "manager.h"
7 #include "rm-rf.h"
8 #include "tests.h"
9 #include "unit.h"
10
11 TEST_RET(default_memory_low, .sd_booted = true) {
12 _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
13 _cleanup_(manager_freep) Manager *m = NULL;
14 Unit *root, *dml,
15 *dml_passthrough, *dml_passthrough_empty, *dml_passthrough_set_dml, *dml_passthrough_set_ml,
16 *dml_override, *dml_override_empty,
17 *dml_discard, *dml_discard_empty, *dml_discard_set_ml;
18 uint64_t dml_tree_default;
19 int r;
20
21 r = enter_cgroup_subroot(NULL);
22 if (r == -ENOMEDIUM)
23 return log_tests_skipped("cgroupfs not available");
24
25 _cleanup_free_ char *unit_dir = NULL;
26 ASSERT_OK(get_testdata_dir("units", &unit_dir));
27 ASSERT_OK(set_unit_path(unit_dir));
28 assert_se(runtime_dir = setup_fake_runtime_dir());
29 r = manager_new(RUNTIME_SCOPE_USER, MANAGER_TEST_RUN_BASIC, &m);
30 if (IN_SET(r, -EPERM, -EACCES)) {
31 log_error_errno(r, "manager_new: %m");
32 return log_tests_skipped("cannot create manager");
33 }
34
35 ASSERT_OK(r);
36 ASSERT_OK(manager_startup(m, NULL, NULL, NULL));
37
38 /* dml.slice has DefaultMemoryLow=50. Beyond that, individual subhierarchies look like this:
39 *
40 * 1. dml-passthrough.slice sets MemoryLow=100. This should not affect its children, as only
41 * DefaultMemoryLow is propagated, not MemoryLow. As such, all leaf services should end up with
42 * memory.low as 50, inherited from dml.slice, *except* for dml-passthrough-set-ml.service, which
43 * should have the value of 0, as it has MemoryLow explicitly set.
44 *
45 * ┌───────────┐
46 * │ dml.slice │
47 * └─────┬─────┘
48 * MemoryLow=100
49 * ┌───────────┴───────────┐
50 * │ dml-passthrough.slice │
51 * └───────────┬───────────┘
52 * ┌───────────────────────────────────┼───────────────────────────────────┐
53 * no new settings DefaultMemoryLow=15 MemoryLow=0
54 * ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐
55 * │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │
56 * └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘
57 *
58 * 2. dml-override.slice sets DefaultMemoryLow=10. As such, dml-override-empty.service should also
59 * end up with a memory.low of 10. dml-override.slice should still have a memory.low of 50.
60 *
61 * ┌───────────┐
62 * │ dml.slice │
63 * └─────┬─────┘
64 * DefaultMemoryLow=10
65 * ┌─────────┴──────────┐
66 * │ dml-override.slice │
67 * └─────────┬──────────┘
68 * no new settings
69 * ┌─────────────┴──────────────┐
70 * │ dml-override-empty.service │
71 * └────────────────────────────┘
72 *
73 * 3. dml-discard.slice sets DefaultMemoryLow= with no rvalue. As such,
74 * dml-discard-empty.service should end up with a value of 0.
75 * dml-discard-set-ml.service sets MemoryLow=15, and as such should have that override the
76 * reset DefaultMemoryLow value. dml-discard.slice should still have an eventual memory.low of 50.
77 *
78 * ┌───────────┐
79 * │ dml.slice │
80 * └─────┬─────┘
81 * DefaultMemoryLow=
82 * ┌─────────┴─────────┐
83 * │ dml-discard.slice │
84 * └─────────┬─────────┘
85 * ┌──────────────┴───────────────┐
86 * no new settings MemoryLow=15
87 * ┌─────────────┴─────────────┐ ┌─────────────┴──────────────┐
88 * │ dml-discard-empty.service │ │ dml-discard-set-ml.service │
89 * └───────────────────────────┘ └────────────────────────────┘
90 */
91 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml.slice", NULL, &dml));
92
93 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-passthrough.slice", NULL, &dml_passthrough));
94 assert_se(UNIT_GET_SLICE(dml_passthrough) == dml);
95 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-passthrough-empty.service", NULL, &dml_passthrough_empty));
96 assert_se(UNIT_GET_SLICE(dml_passthrough_empty) == dml_passthrough);
97 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-dml.service", NULL, &dml_passthrough_set_dml));
98 assert_se(UNIT_GET_SLICE(dml_passthrough_set_dml) == dml_passthrough);
99 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-ml.service", NULL, &dml_passthrough_set_ml));
100 assert_se(UNIT_GET_SLICE(dml_passthrough_set_ml) == dml_passthrough);
101
102 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-override.slice", NULL, &dml_override));
103 assert_se(UNIT_GET_SLICE(dml_override) == dml);
104 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-override-empty.service", NULL, &dml_override_empty));
105 assert_se(UNIT_GET_SLICE(dml_override_empty) == dml_override);
106
107 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-discard.slice", NULL, &dml_discard));
108 assert_se(UNIT_GET_SLICE(dml_discard) == dml);
109 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-discard-empty.service", NULL, &dml_discard_empty));
110 assert_se(UNIT_GET_SLICE(dml_discard_empty) == dml_discard);
111 ASSERT_OK(manager_load_startable_unit_or_warn(m, "dml-discard-set-ml.service", NULL, &dml_discard_set_ml));
112 assert_se(UNIT_GET_SLICE(dml_discard_set_ml) == dml_discard);
113
114 assert_se(root = UNIT_GET_SLICE(dml));
115 assert_se(!UNIT_GET_SLICE(root));
116
117 assert_se(unit_get_ancestor_memory_low(root) == CGROUP_LIMIT_MIN);
118
119 assert_se(unit_get_ancestor_memory_low(dml) == CGROUP_LIMIT_MIN);
120 dml_tree_default = unit_get_cgroup_context(dml)->default_memory_low;
121 assert_se(dml_tree_default == 50);
122
123 assert_se(unit_get_ancestor_memory_low(dml_passthrough) == 100);
124 assert_se(unit_get_ancestor_memory_low(dml_passthrough_empty) == dml_tree_default);
125 assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_dml) == 50);
126 assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 0);
127
128 assert_se(unit_get_ancestor_memory_low(dml_override) == dml_tree_default);
129 assert_se(unit_get_ancestor_memory_low(dml_override_empty) == 10);
130
131 assert_se(unit_get_ancestor_memory_low(dml_discard) == dml_tree_default);
132 assert_se(unit_get_ancestor_memory_low(dml_discard_empty) == CGROUP_LIMIT_MIN);
133 assert_se(unit_get_ancestor_memory_low(dml_discard_set_ml) == 15);
134
135 return 0;
136 }
137
138 DEFINE_TEST_MAIN(LOG_DEBUG);