]>
Commit | Line | Data |
---|---|---|
c52db42b CD |
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 "test-helper.h" | |
9 | #include "tests.h" | |
10 | #include "unit.h" | |
11 | ||
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; | |
15 | Unit *root, *dml, | |
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; | |
20 | int r; | |
21 | ||
22 | r = enter_cgroup_subroot(); | |
23 | if (r == -ENOMEDIUM) | |
24 | return log_tests_skipped("cgroupfs not available"); | |
25 | ||
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"); | |
32 | } | |
33 | ||
34 | assert_se(r >= 0); | |
35 | assert_se(manager_startup(m, NULL, NULL) >= 0); | |
36 | ||
37 | /* dml.slice has DefaultMemoryLow=50. Beyond that, individual subhierarchies look like this: | |
38 | * | |
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 | |
465ace74 | 42 | * should have the value of 0, as it has MemoryLow explicitly set. |
c52db42b CD |
43 | * |
44 | * ┌───────────┐ | |
45 | * │ dml.slice │ | |
46 | * └─────┬─────┘ | |
47 | * MemoryLow=100 | |
48 | * ┌───────────┴───────────┐ | |
49 | * │ dml-passthrough.slice │ | |
50 | * └───────────┬───────────┘ | |
51 | * ┌───────────────────────────────────┼───────────────────────────────────┐ | |
465ace74 | 52 | * no new settings DefaultMemoryLow=15 MemoryLow=0 |
c52db42b CD |
53 | * ┌───────────────┴───────────────┐ ┌────────────────┴────────────────┐ ┌───────────────┴────────────────┐ |
54 | * │ dml-passthrough-empty.service │ │ dml-passthrough-set-dml.service │ │ dml-passthrough-set-ml.service │ | |
55 | * └───────────────────────────────┘ └─────────────────────────────────┘ └────────────────────────────────┘ | |
56 | * | |
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. | |
59 | * | |
60 | * ┌───────────┐ | |
61 | * │ dml.slice │ | |
62 | * └─────┬─────┘ | |
63 | * DefaultMemoryLow=10 | |
64 | * ┌─────────┴──────────┐ | |
65 | * │ dml-override.slice │ | |
66 | * └─────────┬──────────┘ | |
67 | * no new settings | |
68 | * ┌─────────────┴──────────────┐ | |
69 | * │ dml-override-empty.service │ | |
70 | * └────────────────────────────┘ | |
71 | * | |
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. | |
76 | * | |
77 | * ┌───────────┐ | |
78 | * │ dml.slice │ | |
79 | * └─────┬─────┘ | |
80 | * DefaultMemoryLow= | |
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 | * └───────────────────────────┘ └────────────────────────────┘ | |
89 | */ | |
90 | assert_se(manager_load_startable_unit_or_warn(m, "dml.slice", NULL, &dml) >= 0); | |
91 | ||
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); | |
100 | ||
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); | |
105 | ||
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); | |
112 | ||
113 | root = UNIT_DEREF(dml->slice); | |
114 | assert_se(!UNIT_ISSET(root->slice)); | |
115 | ||
116 | assert_se(unit_get_ancestor_memory_low(root) == CGROUP_LIMIT_MIN); | |
117 | ||
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); | |
121 | ||
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); | |
465ace74 | 125 | assert_se(unit_get_ancestor_memory_low(dml_passthrough_set_ml) == 0); |
c52db42b CD |
126 | |
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); | |
129 | ||
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); | |
133 | ||
134 | return 0; | |
135 | } | |
136 | ||
137 | int main(int argc, char* argv[]) { | |
138 | int rc = EXIT_SUCCESS; | |
139 | ||
140 | test_setup_logging(LOG_DEBUG); | |
141 | ||
142 | TEST_REQ_RUNNING_SYSTEMD(rc = test_default_memory_low()); | |
143 | ||
144 | return rc; | |
145 | } |