View | Details | Raw Unified | Return to ticket 16713 | Differences between
and this patch

Collapse All | Expand All

(-)a/src/plugins/cgroup/v2/cgroup_v2.c (-2 / +47 lines)
Lines 122-127 extern int cgroup_p_task_addto(cgroup_ctl_type_t ctl, stepd_step_rec_t *step, Link Here
122
 *                 (task_id = NO_VAL)
122
 *                 (task_id = NO_VAL)
123
 */
123
 */
124
124
125
/*
126
 * Get the relative path to the root of the cgroup namespace by
127
 * reading /proc/PID/mountinfo for the given PID.
128
 *
129
 * In the root cgroup namespace (most environments) we expect that the
130
 * cgroup2 filesystem is mounted on /, such as:
131
 * 34 25 0:29 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:9 - cgroup2 cgroup2 rw
132
 *
133
 * If the given PID is in a cgroup namespace, then it could look like:
134
 * 3526 3512 0:29 /../../../../cont1 /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime - cgroup2 cgroup2 rw
135
 *
136
 * See man:cgroup_namespaces(7).
137
 *
138
 */
139
static char *_get_relative_cg_path(const char *pid)
140
{
141
	char *buf, *p, *ret = NULL, *procfile=NULL, *mount=NULL;
142
	size_t sz, name_len;
143
	int i;
144
145
	xstrfmtcat(procfile, "/proc/%s/mountinfo", pid);
146
	if (common_file_read_content(procfile, &buf, &sz) !=
147
	    SLURM_SUCCESS)
148
		fatal("cannot read /proc/?/mountinfo contents: %m");
149
	debug4("%s contents: %s", procfile, buf);
150
151
	if (!(p = xstrstr(buf, "cgroup2 cgroup2"))) {
152
		fatal("Did not find cgroup2 mount point in %s", procfile);
153
	}
154
155
	*p = '\0';
156
	if ((mount = xstrrchr(buf, '\n')) == NULL)
157
		mount = buf;
158
	debug4("First 8 data of cgroup2 line in %s is %s.", procfile, mount);
159
160
	p = mount;
161
	for (i=0; (i < 4) && (p != NULL); i++)
162
		p = strtok((i==0)?mount:NULL, " ");
163
	if (p == NULL)
164
		fatal("Could not parse cgroup2 mount point in %s.", procfile);
165
	ret = xstrdup(p);
166
	debug2("Relative path to root of cgroup namespace is %s.", ret);
167
	xfree(buf);
168
	xfree(procfile);
169
	return ret;
170
}
171
125
/*
172
/*
126
 * The cgroup v2 documented way to know which is the process root in the cgroup
173
 * The cgroup v2 documented way to know which is the process root in the cgroup
127
 * hierarchy is just to read /proc/self/cgroup. In Unified hierarchies this
174
 * hierarchy is just to read /proc/self/cgroup. In Unified hierarchies this
128
- 
129
--
130
src/plugins/cgroup/v2/cgroup_v2.c | 30 +++++++++++++++++++++++++++---
175
src/plugins/cgroup/v2/cgroup_v2.c | 30 +++++++++++++++++++++++++++---
131
1 file changed, 27 insertions(+), 3 deletions(-)
176
1 file changed, 27 insertions(+), 3 deletions(-)
(-)a/src/plugins/cgroup/v2/cgroup_v2.c (-5 / +27 lines)
Lines 178-188 static char *_get_relative_cg_path(const char *pid) Link Here
178
static char *_get_self_cg_path()
178
static char *_get_self_cg_path()
179
{
179
{
180
	char *buf, *start = NULL, *p, *ret = NULL;
180
	char *buf, *start = NULL, *p, *ret = NULL;
181
	size_t sz;
181
	char *relative_cg_path = NULL;
182
	size_t sz, relative_cg_len;
182
183
183
	if (common_file_read_content("/proc/self/cgroup", &buf, &sz) !=
184
	if (common_file_read_content("/proc/self/cgroup", &buf, &sz) !=
184
	    SLURM_SUCCESS)
185
	    SLURM_SUCCESS)
185
		fatal("cannot read /proc/self/cgroup contents: %m");
186
		fatal("cannot read /proc/self/cgroup contents: %m");
187
	debug4("Self cgroup data is %s.", buf);
186
188
187
	/*
189
	/*
188
	 * In Unified mode there will be just one line containing the path
190
	 * In Unified mode there will be just one line containing the path
Lines 196-201 static char *_get_self_cg_path() Link Here
196
	 * If we have multiple slurmd, we will likely have one unit file per
198
	 * If we have multiple slurmd, we will likely have one unit file per
197
	 * node, and the path takes the name of the service file, e.g:
199
	 * node, and the path takes the name of the service file, e.g:
198
	 * /sys/fs/cgroup/system.slice/slurmd-<nodename>.service/
200
	 * /sys/fs/cgroup/system.slice/slurmd-<nodename>.service/
201
	 *
202
	 * If the cgroup path contains .. then cgroup namespaces are
203
	 * in use.  In this case remove the relative path to the root
204
	 * of the cgroup namespace from our path.
199
	 */
205
	 */
200
	if ((p = xstrchr(buf, ':'))) {
206
	if ((p = xstrchr(buf, ':'))) {
201
		if ((p + 2) < (buf + sz - 1))
207
		if ((p + 2) < (buf + sz - 1))
Lines 205-212 static char *_get_self_cg_path() Link Here
205
	if (start && (*start != '\0')) {
211
	if (start && (*start != '\0')) {
206
		if ((p = xstrchr(start, '\n')))
212
		if ((p = xstrchr(start, '\n')))
207
			*p = '\0';
213
			*p = '\0';
208
		xstrfmtcat(ret, "%s%s",
214
		debug3("Found self cgroup path %s.", start);
209
			   slurm_cgroup_conf.cgroup_mountpoint, start);
215
		if (xstrstr(start, "..")) {
216
			debug3("Relative path to cgroup namespace root found; removing the relative path prefix.");
217
			relative_cg_path = _get_relative_cg_path("self");
218
			if (xstrstr(start, relative_cg_path)) {
219
				relative_cg_len = strlen(relative_cg_path);
220
				xstrfmtcat(ret, "%s%s",
221
					slurm_cgroup_conf.cgroup_mountpoint,
222
					start + relative_cg_len);
223
				debug2("Using %s as my cgroup path.", ret);
224
			} else {
225
				error("Did not find relative path to cgroup namespace root prefix %s in self cgroup path %s.",
226
					relative_cg_path, start);
227
			}
228
			xfree(relative_cg_path);
229
		} else {
230
			debug2("Using constructed cgroup path %s + %s.", slurm_cgroup_conf.cgroup_mountpoint, start);
231
			xstrfmtcat(ret, "%s%s",
232
				   slurm_cgroup_conf.cgroup_mountpoint, start);
233
		}
210
	}
234
	}
211
235
212
	xfree(buf);
236
	xfree(buf);
213
- 
214
--
215
src/plugins/cgroup/v2/cgroup_v2.c | 31 ++++++++++++++++++++++++++++---
237
src/plugins/cgroup/v2/cgroup_v2.c | 31 ++++++++++++++++++++++++++++---
216
1 file changed, 28 insertions(+), 3 deletions(-)
238
1 file changed, 28 insertions(+), 3 deletions(-)
(-)a/src/plugins/cgroup/v2/cgroup_v2.c (-5 / +28 lines)
Lines 246-252 static char *_get_self_cg_path() Link Here
246
 * But in containerized environments it could look like:
246
 * But in containerized environments it could look like:
247
 * "0::/docker.slice/docker-<some UUID>.scope/init.scope"
247
 * "0::/docker.slice/docker-<some UUID>.scope/init.scope"
248
 *
248
 *
249
 * This function just strips the "0::" and "init.scope" portions.
249
 * If cgroup namespaces are in use it could look like:
250
 * 0::/../../../../cont1/init.scope
251
 *
252
 * This function just strips the "0::" and "init.scope" portions and,
253
 * if cgroup namespaces are in use, removes the relative path to the
254
 * root of the cgroup namespace.
250
 *
255
 *
251
 * In normal systems the final path will look like this:
256
 * In normal systems the final path will look like this:
252
 * /sys/fs/cgroup[/]
257
 * /sys/fs/cgroup[/]
Lines 254-268 static char *_get_self_cg_path() Link Here
254
 * In containerized environments it will look like:
259
 * In containerized environments it will look like:
255
 * /sys/fs/cgroup[/docker.slice/docker-<some UUID>.scope]
260
 * /sys/fs/cgroup[/docker.slice/docker-<some UUID>.scope]
256
 *
261
 *
262
 * In cgroup namespaces it will look like:
263
 * /sys/fs/cgroup/init.scope
264
 *
257
 */
265
 */
258
static char *_get_init_cg_path()
266
static char *_get_init_cg_path()
259
{
267
{
260
	char *buf, *start = NULL, *p, *ret = NULL;
268
	char *buf, *start = NULL, *p, *ret = NULL;
261
	size_t sz;
269
	char *relative_cg_path = NULL;
270
	size_t sz, relative_cg_len;
262
271
263
	if (common_file_read_content("/proc/1/cgroup", &buf, &sz) !=
272
	if (common_file_read_content("/proc/1/cgroup", &buf, &sz) !=
264
	    SLURM_SUCCESS)
273
	    SLURM_SUCCESS)
265
		fatal("cannot read /proc/1/cgroup contents: %m");
274
		fatal("cannot read /proc/1/cgroup contents: %m");
275
	debug4("Init cgroup data is %s.", buf);
266
276
267
	/*
277
	/*
268
	 * In Unified mode there will be just one line containing the path
278
	 * In Unified mode there will be just one line containing the path
Lines 282-288 static char *_get_init_cg_path() Link Here
282
		if ((p = xstrchr(start, '\n')))
292
		if ((p = xstrchr(start, '\n')))
283
			*p = '\0';
293
			*p = '\0';
284
		p = xdirname(start);
294
		p = xdirname(start);
285
		if (!xstrcmp(p, "/"))
295
		debug3("Found PID 1 cgroup path %s.", p);
296
		if (xstrstr(p, "..")) {
297
			debug3("Relative path to cgroup namespace root found; removing the relative path prefix.");
298
			relative_cg_path = _get_relative_cg_path("1");
299
			if (xstrstr(p, relative_cg_path)) {
300
				relative_cg_len = strlen(relative_cg_path);
301
				xstrfmtcat(ret, "%s%s",
302
					slurm_cgroup_conf.cgroup_mountpoint,
303
					p + relative_cg_len);
304
				debug2("Using %s as init cgroup path.", ret);
305
			} else {
306
				error("Did not find relative path to cgroup namespace root prefix %s in init cgroup path %s.",
307
					relative_cg_path, start);
308
			}
309
			xfree(relative_cg_path);
310
		} else if (!xstrcmp(p, "/"))
286
			xstrfmtcat(ret, "%s",
311
			xstrfmtcat(ret, "%s",
287
				   slurm_cgroup_conf.cgroup_mountpoint);
312
				   slurm_cgroup_conf.cgroup_mountpoint);
288
		else
313
		else
289
- 
290
--
291
src/plugins/cgroup/v2/cgroup_v2.c | 1 +
314
src/plugins/cgroup/v2/cgroup_v2.c | 1 +
292
1 file changed, 1 insertion(+)
315
1 file changed, 1 insertion(+)
(-)a/src/plugins/cgroup/v2/cgroup_v2.c (-2 / +1 lines)
Lines 2-7 Link Here
2
 *  cgroup_v2.c - Cgroup v2 plugin
2
 *  cgroup_v2.c - Cgroup v2 plugin
3
 *****************************************************************************
3
 *****************************************************************************
4
 *  Copyright (C) 2021 SchedMD LLC
4
 *  Copyright (C) 2021 SchedMD LLC
5
 *  Copyright (C) 2023 Urban Borstnik, ETH Zurich
5
 *  Written by Felip Moll <felip.moll@schedmd.com>
6
 *  Written by Felip Moll <felip.moll@schedmd.com>
6
 *
7
 *
7
 *  This file is part of Slurm, a resource management program.
8
 *  This file is part of Slurm, a resource management program.
8
- 
9
root.
9
root.
10
--
11
src/plugins/cgroup/v2/cgroup_v2.c | 2 +-
10
src/plugins/cgroup/v2/cgroup_v2.c | 2 +-
12
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 1 insertion(+), 1 deletion(-)
(-)a/src/plugins/cgroup/v2/cgroup_v2.c (-2 / +1 lines)
Lines 140-146 extern int cgroup_p_task_addto(cgroup_ctl_type_t ctl, stepd_step_rec_t *step, Link Here
140
static char *_get_relative_cg_path(const char *pid)
140
static char *_get_relative_cg_path(const char *pid)
141
{
141
{
142
	char *buf, *p, *ret = NULL, *procfile=NULL, *mount=NULL;
142
	char *buf, *p, *ret = NULL, *procfile=NULL, *mount=NULL;
143
	size_t sz, name_len;
143
	size_t sz;
144
	int i;
144
	int i;
145
145
146
	xstrfmtcat(procfile, "/proc/%s/mountinfo", pid);
146
	xstrfmtcat(procfile, "/proc/%s/mountinfo", pid);
147
- 

Return to ticket 16713