]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-cgroup-unit-default.c
Merge pull request #14010 from poettering/localtime-symlink
[thirdparty/systemd.git] / src / test / test-cgroup-unit-default.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
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 static int test_default_memory_low(void) {
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 assert_se(set_unit_path(get_testdata_dir()) >= 0);
26 assert_se(runtime_dir = setup_fake_runtime_dir());
27 r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m);
28 if (IN_SET(r, -EPERM, -EACCES)) {
29 log_error_errno(r, "manager_new: %m");
30 return log_tests_skipped("cannot create manager");
31 }
32
33 assert_se(r >= 0);
34 assert_se(manager_startup(m, NULL, NULL) >= 0);
35
36 /* dml.slice has DefaultMemoryLow=50. Beyond that, individual subhierarchies look like this:
37 *
38 * 1. dml-passthrough.slice sets MemoryLow=100. This should not affect its children, as only
39 * DefaultMemoryLow is propagated, not MemoryLow. As such, all leaf services should end up with
40 * memory.low as 50, inherited from dml.slice, *except* for dml-passthrough-set-ml.service, which
41 * should have the value of 0, as it has MemoryLow explicitly set.
42 *
43 * ┌───────────┐
44 * │ dml.slice │
45 * └─────┬─────┘
46 * MemoryLow=100
47 * ┌───────────┴───────────┐
48 * │ dml-passthrough.slice │
49 * └───────────┬───────────┘
50 * ┌───────────────────────────────────┼───────────────────────────────────┐
51 * no new settings DefaultMemoryLow=15 MemoryLow=0
52 * ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐
53 * │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │
54 * └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘
55 *
56 * 2. dml-override.slice sets DefaultMemoryLow=10. As such, dml-override-empty.service should also
57 * end up with a memory.low of 10. dml-override.slice should still have a memory.low of 50.
58 *
59 * ┌───────────┐
60 * │ dml.slice │
61 * └─────┬─────┘
62 * DefaultMemoryLow=10
63 * ┌─────────┴──────────┐
64 * │ dml-override.slice │
65 * └─────────┬──────────┘
66 * no new settings
67 * ┌─────────────┴──────────────┐
68 * │ dml-override-empty.service │
69 * └────────────────────────────┘
70 *
71 * 3. dml-discard.slice sets DefaultMemoryLow= with no rvalue. As such,
72 * dml-discard-empty.service should end up with a value of 0.
73 * dml-discard-explicit-ml.service sets MemoryLow=70, and as such should have that override the
74 * reset DefaultMemoryLow value. dml-discard.slice should still have an eventual memory.low of 50.
75 *
76 * ┌───────────┐
77 * │ dml.slice │
78 * └─────┬─────┘
79 * DefaultMemoryLow=
80 * ┌─────────┴─────────┐
81 * │ dml-discard.slice │
82 * └─────────┬─────────┘
83 * ┌──────────────┴───────────────┐
84 * no new settings MemoryLow=15
85 * ┌─────────────┴─────────────┐ ┌─────────────┴──────────────┐
86 * │ dml-discard-empty.service │ │ dml-discard-set-ml.service │
87 * └───────────────────────────┘ └────────────────────────────┘
88 */
89 assert_se(manager_load_startable_unit_or_warn(m, "dml.slice", NULL, &dml) >= 0);
90
91 assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough.slice", NULL, &dml_passthrough) >= 0);
92 assert_se(UNIT_DEREF(dml_passthrough->slice) == dml);
93 assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-empty.service", NULL, &dml_passthrough_empty) >= 0);
94 assert_se(UNIT_DEREF(dml_passthrough_empty->slice) == dml_passthrough);
95 assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-dml.service", NULL, &dml_passthrough_set_dml) >= 0);
96 assert_se(UNIT_DEREF(dml_passthrough_set_dml->slice) == dml_passthrough);
97 assert_se(manager_load_startable_unit_or_warn(m, "dml-passthrough-set-ml.service", NULL, &dml_passthrough_set_ml) >= 0);
98 assert_se(UNIT_DEREF(dml_passthrough_set_ml->slice) == dml_passthrough);
99
100 assert_se(manager_load_startable_unit_or_warn(m, "dml-override.slice", NULL, &dml_override) >= 0);
101 assert_se(UNIT_DEREF(dml_override->slice) == dml);
102 assert_se(manager_load_startable_unit_or_warn(m, "dml-override-empty.service", NULL, &dml_override_empty) >= 0);
103 assert_se(UNIT_DEREF(dml_override_empty->slice) == dml_override);
104
105 assert_se(manager_load_startable_unit_or_warn(m, "dml-discard.slice", NULL, &dml_discard) >= 0);
106 assert_se(UNIT_DEREF(dml_discard->slice) == dml);
107 assert_se(manager_load_startable_unit_or_warn(m, "dml-discard-empty.service", NULL, &dml_discard_empty) >= 0);
108 assert_se(UNIT_DEREF(dml_discard_empty->slice) == dml_discard);
109 assert_se(manager_load_startable_unit_or_warn(m, "dml-discard-set-ml.service", NULL, &dml_discard_set_ml) >= 0);
110 assert_se(UNIT_DEREF(dml_discard_set_ml->slice) == dml_discard);
111
112 root = UNIT_DEREF(dml->slice);
113 assert_se(!UNIT_ISSET(root->slice));
114
115 assert_se(unit_get_ancestor_memory_low(root) == CGROUP_LIMIT_MIN);
116
117 assert_se(unit_get_ancestor_memory_low(dml) == CGROUP_LIMIT_MIN);
118 dml_tree_default = unit_get_cgroup_context(dml)->default_memory_low;
119 assert_se(dml_tree_default == 50);
120
121 assert_se(unit_get_ancestor_memory_low(dml_passthrough) == 100);
122 assert_se(unit_get_ancestor_memory_low(dml_passthrough_empty) == dml_tree_default);
123 assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_dml) == 50);
124 assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 0);
125
126 assert_se(unit_get_ancestor_memory_low(dml_override) == dml_tree_default);
127 assert_se(unit_get_ancestor_memory_low(dml_override_empty) == 10);
128
129 assert_se(unit_get_ancestor_memory_low(dml_discard) == dml_tree_default);
130 assert_se(unit_get_ancestor_memory_low(dml_discard_empty) == CGROUP_LIMIT_MIN);
131 assert_se(unit_get_ancestor_memory_low(dml_discard_set_ml) == 15);
132
133 return 0;
134 }
135
136 int main(int argc, char* argv[]) {
137 int rc = EXIT_SUCCESS;
138
139 test_setup_logging(LOG_DEBUG);
140
141 TEST_REQ_RUNNING_SYSTEMD(rc = test_default_memory_low());
142
143 return rc;
144 }