Skip to content

Commit 19ccccc

Browse files
Jonathan Dowlandjerboaa
Jonathan Dowland
authored andcommitted
8253435: Cgroup: 'stomping of _mount_path' crash if manually mounted cpusets exist
Backport-of: 0054c15
1 parent 3cf4e70 commit 19ccccc

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

src/hotspot/os/linux/cgroupSubsystem_linux.cpp

+16-2
Original file line numberDiff line numberDiff line change
@@ -302,8 +302,22 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
302302
cg_infos[MEMORY_IDX]._root_mount_path = os::strdup(tmproot);
303303
cg_infos[MEMORY_IDX]._data_complete = true;
304304
} else if (strcmp(token, "cpuset") == 0) {
305-
assert(cg_infos[CPUSET_IDX]._mount_path == NULL, "stomping of _mount_path");
306-
cg_infos[CPUSET_IDX]._mount_path = os::strdup(tmpmount);
305+
if (cg_infos[CPUSET_IDX]._mount_path != NULL) {
306+
// On some systems duplicate cpuset controllers get mounted in addition to
307+
// the main cgroup controllers most likely under /sys/fs/cgroup. In that
308+
// case pick the one under /sys/fs/cgroup and discard others.
309+
if (strstr(cg_infos[CPUSET_IDX]._mount_path, "/sys/fs/cgroup") != cg_infos[CPUSET_IDX]._mount_path) {
310+
log_warning(os, container)("Duplicate cpuset controllers detected. Picking %s, skipping %s.",
311+
tmpmount, cg_infos[CPUSET_IDX]._mount_path);
312+
os::free(cg_infos[CPUSET_IDX]._mount_path);
313+
cg_infos[CPUSET_IDX]._mount_path = os::strdup(tmpmount);
314+
} else {
315+
log_warning(os, container)("Duplicate cpuset controllers detected. Picking %s, skipping %s.",
316+
cg_infos[CPUSET_IDX]._mount_path, tmpmount);
317+
}
318+
} else {
319+
cg_infos[CPUSET_IDX]._mount_path = os::strdup(tmpmount);
320+
}
307321
cg_infos[CPUSET_IDX]._root_mount_path = os::strdup(tmproot);
308322
cg_infos[CPUSET_IDX]._data_complete = true;
309323
} else if (strcmp(token, "cpu") == 0) {

test/hotspot/jtreg/containers/cgroup/CgroupSubsystemFactory.java

+24-1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ public class CgroupSubsystemFactory {
6161
private Path cgroupv1CgInfoNonZeroHierarchy;
6262
private Path cgroupv1MntInfoNonZeroHierarchyOtherOrder;
6363
private Path cgroupv1MntInfoNonZeroHierarchy;
64+
private Path cgroupv1MntInfoDoubleCpuset;
65+
private Path cgroupv1MntInfoDoubleCpuset2;
6466
private String mntInfoEmpty = "";
6567
private Path cgroupV1SelfCgroup;
6668
private Path cgroupV2SelfCgroup;
@@ -103,11 +105,14 @@ public class CgroupSubsystemFactory {
103105
"41 30 0:37 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:13 - cgroup none rw,seclabel,devices\n" +
104106
"42 30 0:38 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:14 - cgroup none rw,seclabel,cpuset\n" +
105107
"43 30 0:39 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:15 - cgroup none rw,seclabel,blkio\n" +
106-
"44 30 0:40 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:16 - cgroup none rw,seclabel,freezer";
108+
"44 30 0:40 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:16 - cgroup none rw,seclabel,freezer\n";
107109
private String mntInfoHybridRest = cgroupv1MountInfoLineMemory + mntInfoHybridStub;
108110
private String mntInfoHybridMissingMemory = mntInfoHybridStub;
109111
private String mntInfoHybrid = cgroupV2LineHybrid + mntInfoHybridRest;
110112
private String mntInfoHybridFlippedOrder = mntInfoHybridRest + cgroupV2LineHybrid;
113+
private String mntInfoCgroupv1MoreCpusetLine = "121 32 0:37 / /cpusets rw,relatime shared:69 - cgroup none rw,cpuset\n";
114+
private String mntInfoCgroupv1DoubleCpuset = mntInfoCgroupv1MoreCpusetLine + mntInfoHybrid;
115+
private String mntInfoCgroupv1DoubleCpuset2 = mntInfoHybrid + mntInfoCgroupv1MoreCpusetLine;
111116
private String cgroupsNonZeroHierarchy =
112117
"#subsys_name hierarchy num_cgroups enabled\n" +
113118
"cpuset 3 1 1\n" +
@@ -158,6 +163,12 @@ private void setup() {
158163

159164
cgroupV2MntInfoMissingCgroupv2 = Paths.get(existingDirectory.toString(), "mnt_info_missing_cgroup2");
160165
Files.writeString(cgroupV2MntInfoMissingCgroupv2, mntInfoHybridStub);
166+
167+
cgroupv1MntInfoDoubleCpuset = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_cpuset");
168+
Files.writeString(cgroupv1MntInfoDoubleCpuset, mntInfoCgroupv1DoubleCpuset);
169+
170+
cgroupv1MntInfoDoubleCpuset2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_cpuset2");
171+
Files.writeString(cgroupv1MntInfoDoubleCpuset2, mntInfoCgroupv1DoubleCpuset2);
161172
} catch (IOException e) {
162173
throw new RuntimeException(e);
163174
}
@@ -175,6 +186,16 @@ private boolean isValidCgroup(int value) {
175186
return value == CGROUPS_V1 || value == CGROUPS_V2;
176187
}
177188

189+
public void testCgroupv1MultipleCpusetMounts(WhiteBox wb, Path mountInfo) {
190+
String procCgroups = cgroupv1CgInfoNonZeroHierarchy.toString();
191+
String procSelfCgroup = cgroupV1SelfCgroup.toString();
192+
String procSelfMountinfo = mountInfo.toString();
193+
int retval = wb.validateCgroup(procCgroups, procSelfCgroup, procSelfMountinfo);
194+
Asserts.assertEQ(CGROUPS_V1, retval, "Multiple cpuset controllers, but only one in /sys/fs/cgroup");
195+
Asserts.assertTrue(isValidCgroup(retval));
196+
System.out.println("testCgroupv1MultipleCpusetMounts PASSED!");
197+
}
198+
178199
public void testCgroupv1NoMounts(WhiteBox wb) {
179200
String procCgroups = cgroupv1CgInfoZeroHierarchy.toString();
180201
String procSelfCgroup = cgroupV1SelfCgroup.toString();
@@ -247,6 +268,8 @@ public static void main(String[] args) throws Exception {
247268
test.testCgroupV1HybridMntInfoOrder(wb);
248269
test.testCgroupv1MissingMemoryController(wb);
249270
test.testCgroupv2NoCgroup2Fs(wb);
271+
test.testCgroupv1MultipleCpusetMounts(wb, test.cgroupv1MntInfoDoubleCpuset);
272+
test.testCgroupv1MultipleCpusetMounts(wb, test.cgroupv1MntInfoDoubleCpuset2);
250273
} finally {
251274
test.teardown();
252275
}

0 commit comments

Comments
 (0)