]>
Commit | Line | Data |
---|---|---|
080abced WB |
1 | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
2 | From: Wolfgang Bumiller <w.bumiller@proxmox.com> | |
3 | Date: Thu, 2 Apr 2020 10:01:37 +0200 | |
4 | Subject: [PATCH] introduce lxc.cgroup.dir.{monitor,container,container.inner} | |
5 | ||
6 | This is a new approach to #1302 with a container-side | |
7 | configuration instead of a global boolean flag. | |
8 | ||
9 | Contrary to the previous PR using an optional additional | |
10 | parameter for the get-cgroup command, this introduces two | |
11 | new additional commands to get the limiting cgroup path and | |
12 | cgroup2 file descriptor. If the limiting option is not in | |
13 | use, these behave identical to their full-path counterparts. | |
14 | ||
15 | If these variables are used the payload will end up in the | |
16 | concatenation of lxc.cgroup.dir.container and | |
17 | lxc.cgroup.dir.container.inner (which may be empty), and the | |
18 | monitor will end up in lxc.cgruop.dir.monitor. The | |
19 | directories are fixed, no retry count logic is applied, | |
20 | failing to create these directories will simply be a hard | |
21 | error. | |
22 | ||
23 | Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com> | |
24 | --- | |
25 | doc/lxc.container.conf.sgml.in | 47 +++++++++++++ | |
26 | src/lxc/commands.c | 5 +- | |
27 | src/lxc/conf.c | 3 + | |
28 | src/lxc/confile.c | 124 +++++++++++++++++++++++++++++++++ | |
29 | 4 files changed, 177 insertions(+), 2 deletions(-) | |
30 | ||
31 | diff --git a/doc/lxc.container.conf.sgml.in b/doc/lxc.container.conf.sgml.in | |
32 | index 3ed71c214..a9c87fe2a 100644 | |
33 | --- a/doc/lxc.container.conf.sgml.in | |
34 | +++ b/doc/lxc.container.conf.sgml.in | |
35 | @@ -1571,6 +1571,53 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
36 | </para> | |
37 | </listitem> | |
38 | </varlistentry> | |
39 | + <varlistentry> | |
40 | + <term> | |
41 | + <option>lxc.cgroup.dir.container</option> | |
42 | + </term> | |
43 | + <listitem> | |
44 | + <para> | |
45 | + This is similar to <option>lxc.cgroup.dir</option>, but must be | |
46 | + used together with <option>lxc.cgroup.dir.monitor</option> and | |
47 | + affects only the container's cgroup path. This option is mutually | |
48 | + exclusive with <option>lxc.cgroup.dir</option>. | |
49 | + Note that the final path the container attaches to may be | |
50 | + extended further by the | |
51 | + <option>lxc.cgroup.dir.container.namespace</option> option. | |
52 | + </para> | |
53 | + </listitem> | |
54 | + </varlistentry> | |
55 | + <varlistentry> | |
56 | + <term> | |
57 | + <option>lxc.cgroup.dir.monitor</option> | |
58 | + </term> | |
59 | + <listitem> | |
60 | + <para> | |
61 | + This is the monitor process counterpart to | |
62 | + <option>lxc.cgroup.dir.container</option>. | |
63 | + </para> | |
64 | + </listitem> | |
65 | + </varlistentry> | |
66 | + <varlistentry> | |
67 | + <term> | |
68 | + <option>lxc.cgroup.dir.container.namespace</option> | |
69 | + </term> | |
70 | + <listitem> | |
71 | + <para> | |
72 | + Specify an additional subdirectory where the cgroup namespace | |
73 | + will be created. With this option, the cgroup limits will be | |
74 | + applied to the outer path specified in | |
75 | + <option>lxc.cgroup.dir.container</option>, which is not accessible | |
76 | + from within the container, making it possible to better enforce | |
77 | + limits for privileged containers in a way they cannot override | |
78 | + them. | |
79 | + This only works in conjunction with the | |
80 | + <option>lxc.cgroup.dir.container</option> and | |
81 | + <option>lxc.cgroup.dir.monitor</option> options and has otherwise | |
82 | + no effect. | |
83 | + </para> | |
84 | + </listitem> | |
85 | + </varlistentry> | |
86 | <varlistentry> | |
87 | <term> | |
88 | <option>lxc.cgroup.relative</option> | |
89 | diff --git a/src/lxc/commands.c b/src/lxc/commands.c | |
90 | index b6ae101fc..44714f9ba 100644 | |
91 | --- a/src/lxc/commands.c | |
92 | +++ b/src/lxc/commands.c | |
93 | @@ -622,7 +622,7 @@ static int lxc_cmd_get_limiting_cgroup_callback(int fd, struct lxc_cmd_req *req, | |
94 | struct lxc_handler *handler, | |
95 | struct lxc_epoll_descr *descr) | |
96 | { | |
97 | - return ret_errno(ENOSYS); | |
98 | + return lxc_cmd_get_cgroup_callback_do(fd, req, handler, descr, true); | |
99 | } | |
100 | ||
101 | /* | |
102 | @@ -1472,7 +1472,8 @@ static int lxc_cmd_get_limiting_cgroup2_fd_callback(int fd, | |
103 | struct lxc_handler *handler, | |
104 | struct lxc_epoll_descr *descr) | |
105 | { | |
106 | - return ret_errno(ENOSYS); | |
107 | + return lxc_cmd_get_cgroup2_fd_callback_do(fd, req, handler, descr, | |
108 | + true); | |
109 | } | |
110 | ||
111 | static int lxc_cmd_process(int fd, struct lxc_cmd_req *req, | |
112 | diff --git a/src/lxc/conf.c b/src/lxc/conf.c | |
113 | index 00789961c..4aafca3cb 100644 | |
114 | --- a/src/lxc/conf.c | |
115 | +++ b/src/lxc/conf.c | |
116 | @@ -3750,6 +3750,9 @@ void lxc_conf_free(struct lxc_conf *conf) | |
117 | lxc_clear_apparmor_raw(conf); | |
118 | lxc_clear_namespace(conf); | |
119 | free(conf->cgroup_meta.dir); | |
120 | + free(conf->cgroup_meta.monitor_dir); | |
121 | + free(conf->cgroup_meta.container_dir); | |
122 | + free(conf->cgroup_meta.namespace_dir); | |
123 | free(conf->cgroup_meta.controllers); | |
124 | free(conf->shmount.path_host); | |
125 | free(conf->shmount.path_cont); | |
126 | diff --git a/src/lxc/confile.c b/src/lxc/confile.c | |
127 | index 4c27e7d4b..899dcd454 100644 | |
128 | --- a/src/lxc/confile.c | |
129 | +++ b/src/lxc/confile.c | |
130 | @@ -71,6 +71,9 @@ lxc_config_define(cap_keep); | |
131 | lxc_config_define(cgroup_controller); | |
132 | lxc_config_define(cgroup2_controller); | |
133 | lxc_config_define(cgroup_dir); | |
134 | +lxc_config_define(cgroup_monitor_dir); | |
135 | +lxc_config_define(cgroup_container_dir); | |
136 | +lxc_config_define(cgroup_container_inner_dir); | |
137 | lxc_config_define(cgroup_relative); | |
138 | lxc_config_define(console_buffer_size); | |
139 | lxc_config_define(console_logfile); | |
140 | @@ -170,6 +173,9 @@ static struct lxc_config_t config_jump_table[] = { | |
141 | { "lxc.cap.drop", set_config_cap_drop, get_config_cap_drop, clr_config_cap_drop, }, | |
142 | { "lxc.cap.keep", set_config_cap_keep, get_config_cap_keep, clr_config_cap_keep, }, | |
143 | { "lxc.cgroup2", set_config_cgroup2_controller, get_config_cgroup2_controller, clr_config_cgroup2_controller, }, | |
144 | + { "lxc.cgroup.dir.monitor", set_config_cgroup_monitor_dir, get_config_cgroup_monitor_dir, clr_config_cgroup_monitor_dir, }, | |
145 | + { "lxc.cgroup.dir.container", set_config_cgroup_container_dir, get_config_cgroup_container_dir, clr_config_cgroup_container_dir, }, | |
146 | + { "lxc.cgroup.dir.container.inner",set_config_cgroup_container_inner_dir, get_config_cgroup_container_inner_dir, clr_config_cgroup_container_inner_dir,}, | |
147 | { "lxc.cgroup.dir", set_config_cgroup_dir, get_config_cgroup_dir, clr_config_cgroup_dir, }, | |
148 | { "lxc.cgroup.relative", set_config_cgroup_relative, get_config_cgroup_relative, clr_config_cgroup_relative, }, | |
149 | { "lxc.cgroup", set_config_cgroup_controller, get_config_cgroup_controller, clr_config_cgroup_controller, }, | |
150 | @@ -1725,6 +1731,48 @@ static int set_config_cgroup_dir(const char *key, const char *value, | |
151 | return set_config_string_item(&lxc_conf->cgroup_meta.dir, value); | |
152 | } | |
153 | ||
154 | +static int set_config_cgroup_monitor_dir(const char *key, const char *value, | |
155 | + struct lxc_conf *lxc_conf, void *data) | |
156 | +{ | |
157 | + if (lxc_config_value_empty(value)) | |
158 | + return clr_config_cgroup_monitor_dir(key, lxc_conf, NULL); | |
159 | + | |
160 | + return set_config_string_item(&lxc_conf->cgroup_meta.monitor_dir, | |
161 | + value); | |
162 | +} | |
163 | + | |
164 | +static int set_config_cgroup_container_dir(const char *key, const char *value, | |
165 | + struct lxc_conf *lxc_conf, | |
166 | + void *data) | |
167 | +{ | |
168 | + if (lxc_config_value_empty(value)) | |
169 | + return clr_config_cgroup_container_dir(key, lxc_conf, NULL); | |
170 | + | |
171 | + return set_config_string_item(&lxc_conf->cgroup_meta.container_dir, | |
172 | + value); | |
173 | +} | |
174 | + | |
175 | +static int set_config_cgroup_container_inner_dir(const char *key, | |
176 | + const char *value, | |
177 | + struct lxc_conf *lxc_conf, | |
178 | + void *data) | |
179 | +{ | |
180 | + if (lxc_config_value_empty(value)) | |
181 | + return clr_config_cgroup_container_inner_dir(key, lxc_conf, | |
182 | + NULL); | |
183 | + | |
184 | + if (strchr(value, '/') || | |
185 | + strcmp(value, ".") == 0 || | |
186 | + strcmp(value, "..") == 0) | |
187 | + { | |
188 | + ERROR("lxc.cgroup.dir.container.inner must be a single directory name"); | |
189 | + return -1; | |
190 | + } | |
191 | + | |
192 | + return set_config_string_item(&lxc_conf->cgroup_meta.namespace_dir, | |
193 | + value); | |
194 | +} | |
195 | + | |
196 | static int set_config_cgroup_relative(const char *key, const char *value, | |
197 | struct lxc_conf *lxc_conf, void *data) | |
198 | { | |
199 | @@ -3648,6 +3696,58 @@ static int get_config_cgroup_dir(const char *key, char *retv, int inlen, | |
200 | return fulllen; | |
201 | } | |
202 | ||
203 | +static int get_config_cgroup_monitor_dir(const char *key, char *retv, int inlen, | |
204 | + struct lxc_conf *lxc_conf, void *data) | |
205 | +{ | |
206 | + int len; | |
207 | + int fulllen = 0; | |
208 | + | |
209 | + if (!retv) | |
210 | + inlen = 0; | |
211 | + else | |
212 | + memset(retv, 0, inlen); | |
213 | + | |
214 | + strprint(retv, inlen, "%s", lxc_conf->cgroup_meta.monitor_dir); | |
215 | + | |
216 | + return fulllen; | |
217 | +} | |
218 | + | |
219 | +static int get_config_cgroup_container_dir(const char *key, char *retv, | |
220 | + int inlen, | |
221 | + struct lxc_conf *lxc_conf, | |
222 | + void *data) | |
223 | +{ | |
224 | + int len; | |
225 | + int fulllen = 0; | |
226 | + | |
227 | + if (!retv) | |
228 | + inlen = 0; | |
229 | + else | |
230 | + memset(retv, 0, inlen); | |
231 | + | |
232 | + strprint(retv, inlen, "%s", lxc_conf->cgroup_meta.container_dir); | |
233 | + | |
234 | + return fulllen; | |
235 | +} | |
236 | + | |
237 | +static int get_config_cgroup_container_inner_dir(const char *key, char *retv, | |
238 | + int inlen, | |
239 | + struct lxc_conf *lxc_conf, | |
240 | + void *data) | |
241 | +{ | |
242 | + int len; | |
243 | + int fulllen = 0; | |
244 | + | |
245 | + if (!retv) | |
246 | + inlen = 0; | |
247 | + else | |
248 | + memset(retv, 0, inlen); | |
249 | + | |
250 | + strprint(retv, inlen, "%s", lxc_conf->cgroup_meta.namespace_dir); | |
251 | + | |
252 | + return fulllen; | |
253 | +} | |
254 | + | |
255 | static inline int get_config_cgroup_relative(const char *key, char *retv, | |
256 | int inlen, struct lxc_conf *lxc_conf, | |
257 | void *data) | |
258 | @@ -4462,6 +4562,30 @@ static int clr_config_cgroup_dir(const char *key, struct lxc_conf *lxc_conf, | |
259 | return 0; | |
260 | } | |
261 | ||
262 | +static int clr_config_cgroup_monitor_dir(const char *key, | |
263 | + struct lxc_conf *lxc_conf, | |
264 | + void *data) | |
265 | +{ | |
266 | + free_disarm(lxc_conf->cgroup_meta.monitor_dir); | |
267 | + return 0; | |
268 | +} | |
269 | + | |
270 | +static int clr_config_cgroup_container_dir(const char *key, | |
271 | + struct lxc_conf *lxc_conf, | |
272 | + void *data) | |
273 | +{ | |
274 | + free_disarm(lxc_conf->cgroup_meta.container_dir); | |
275 | + return 0; | |
276 | +} | |
277 | + | |
278 | +static int clr_config_cgroup_container_inner_dir(const char *key, | |
279 | + struct lxc_conf *lxc_conf, | |
280 | + void *data) | |
281 | +{ | |
282 | + free_disarm(lxc_conf->cgroup_meta.namespace_dir); | |
283 | + return 0; | |
284 | +} | |
285 | + | |
286 | static inline int clr_config_cgroup_relative(const char *key, | |
287 | struct lxc_conf *lxc_conf, | |
288 | void *data) |