Skip to content

Commit 8f3bbe9

Browse files
casparcwangjerboaa
authored andcommitted
8293472: Incorrect container resource limit detection if manual cgroup fs mounts present
Reviewed-by: sgehwolf, iklam
1 parent 1caba0f commit 8f3bbe9

File tree

6 files changed

+135
-54
lines changed

6 files changed

+135
-54
lines changed

src/hotspot/os/linux/cgroupSubsystem_linux.cpp

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,32 @@ CgroupSubsystem* CgroupSubsystemFactory::create() {
123123
return new CgroupV1Subsystem(cpuset, cpu, cpuacct, pids, memory);
124124
}
125125

126+
void CgroupSubsystemFactory::set_controller_paths(CgroupInfo* cg_infos,
127+
int controller,
128+
const char* name,
129+
char* mount_path,
130+
char* root_path) {
131+
if (cg_infos[controller]._mount_path != NULL) {
132+
// On some systems duplicate controllers get mounted in addition to
133+
// the main cgroup controllers most likely under /sys/fs/cgroup. In that
134+
// case pick the one under /sys/fs/cgroup and discard others.
135+
if (strstr(cg_infos[controller]._mount_path, "/sys/fs/cgroup") != cg_infos[controller]._mount_path) {
136+
log_debug(os, container)("Duplicate %s controllers detected. Picking %s, skipping %s.",
137+
name, mount_path, cg_infos[controller]._mount_path);
138+
os::free(cg_infos[controller]._mount_path);
139+
os::free(cg_infos[controller]._root_mount_path);
140+
cg_infos[controller]._mount_path = os::strdup(mount_path);
141+
cg_infos[controller]._root_mount_path = os::strdup(root_path);
142+
} else {
143+
log_debug(os, container)("Duplicate %s controllers detected. Picking %s, skipping %s.",
144+
name, cg_infos[controller]._mount_path, mount_path);
145+
}
146+
} else {
147+
cg_infos[controller]._mount_path = os::strdup(mount_path);
148+
cg_infos[controller]._root_mount_path = os::strdup(root_path);
149+
}
150+
}
151+
126152
bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
127153
const char* proc_cgroups,
128154
const char* proc_self_cgroup,
@@ -288,7 +314,6 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
288314
bool cgroupv2_mount_point_found = false;
289315
bool any_cgroup_mounts_found = false;
290316
while ((p = fgets(buf, MAXPATHLEN, mntinfo)) != NULL) {
291-
char tmp_mount_point[MAXPATHLEN+1];
292317
char tmp_fs_type[MAXPATHLEN+1];
293318
char tmproot[MAXPATHLEN+1];
294319
char tmpmount[MAXPATHLEN+1];
@@ -299,15 +324,13 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
299324
// Cgroup v2 relevant info. We only look for the _mount_path iff is_cgroupsV2 so
300325
// as to avoid memory stomping of the _mount_path pointer later on in the cgroup v1
301326
// block in the hybrid case.
302-
//
303-
if (is_cgroupsV2 && sscanf(p, "%*d %*d %*d:%*d %*s %s %*[^-]- %s %*s %*s", tmp_mount_point, tmp_fs_type) == 2) {
327+
if (is_cgroupsV2 && sscanf(p, "%*d %*d %*d:%*d %s %s %*[^-]- %s %*s %*s", tmproot, tmpmount, tmp_fs_type) == 3) {
304328
// we likely have an early match return (e.g. cgroup fs match), be sure we have cgroup2 as fstype
305-
if (!cgroupv2_mount_point_found && strcmp("cgroup2", tmp_fs_type) == 0) {
329+
if (strcmp("cgroup2", tmp_fs_type) == 0) {
306330
cgroupv2_mount_point_found = true;
307331
any_cgroup_mounts_found = true;
308332
for (int i = 0; i < CG_INFO_LENGTH; i++) {
309-
assert(cg_infos[i]._mount_path == NULL, "_mount_path memory stomping");
310-
cg_infos[i]._mount_path = os::strdup(tmp_mount_point);
333+
set_controller_paths(cg_infos, i, "(cg2, unified)", tmpmount, tmproot);
311334
}
312335
}
313336
}
@@ -332,47 +355,23 @@ bool CgroupSubsystemFactory::determine_type(CgroupInfo* cg_infos,
332355
while ((token = strsep(&cptr, ",")) != NULL) {
333356
if (strcmp(token, "memory") == 0) {
334357
any_cgroup_mounts_found = true;
335-
assert(cg_infos[MEMORY_IDX]._mount_path == NULL, "stomping of _mount_path");
336-
cg_infos[MEMORY_IDX]._mount_path = os::strdup(tmpmount);
337-
cg_infos[MEMORY_IDX]._root_mount_path = os::strdup(tmproot);
358+
set_controller_paths(cg_infos, MEMORY_IDX, token, tmpmount, tmproot);
338359
cg_infos[MEMORY_IDX]._data_complete = true;
339360
} else if (strcmp(token, "cpuset") == 0) {
340361
any_cgroup_mounts_found = true;
341-
if (cg_infos[CPUSET_IDX]._mount_path != NULL) {
342-
// On some systems duplicate cpuset controllers get mounted in addition to
343-
// the main cgroup controllers most likely under /sys/fs/cgroup. In that
344-
// case pick the one under /sys/fs/cgroup and discard others.
345-
if (strstr(cg_infos[CPUSET_IDX]._mount_path, "/sys/fs/cgroup") != cg_infos[CPUSET_IDX]._mount_path) {
346-
log_warning(os, container)("Duplicate cpuset controllers detected. Picking %s, skipping %s.",
347-
tmpmount, cg_infos[CPUSET_IDX]._mount_path);
348-
os::free(cg_infos[CPUSET_IDX]._mount_path);
349-
cg_infos[CPUSET_IDX]._mount_path = os::strdup(tmpmount);
350-
} else {
351-
log_warning(os, container)("Duplicate cpuset controllers detected. Picking %s, skipping %s.",
352-
cg_infos[CPUSET_IDX]._mount_path, tmpmount);
353-
}
354-
} else {
355-
cg_infos[CPUSET_IDX]._mount_path = os::strdup(tmpmount);
356-
}
357-
cg_infos[CPUSET_IDX]._root_mount_path = os::strdup(tmproot);
362+
set_controller_paths(cg_infos, CPUSET_IDX, token, tmpmount, tmproot);
358363
cg_infos[CPUSET_IDX]._data_complete = true;
359364
} else if (strcmp(token, "cpu") == 0) {
360365
any_cgroup_mounts_found = true;
361-
assert(cg_infos[CPU_IDX]._mount_path == NULL, "stomping of _mount_path");
362-
cg_infos[CPU_IDX]._mount_path = os::strdup(tmpmount);
363-
cg_infos[CPU_IDX]._root_mount_path = os::strdup(tmproot);
366+
set_controller_paths(cg_infos, CPU_IDX, token, tmpmount, tmproot);
364367
cg_infos[CPU_IDX]._data_complete = true;
365368
} else if (strcmp(token, "cpuacct") == 0) {
366369
any_cgroup_mounts_found = true;
367-
assert(cg_infos[CPUACCT_IDX]._mount_path == NULL, "stomping of _mount_path");
368-
cg_infos[CPUACCT_IDX]._mount_path = os::strdup(tmpmount);
369-
cg_infos[CPUACCT_IDX]._root_mount_path = os::strdup(tmproot);
370+
set_controller_paths(cg_infos, CPUACCT_IDX, token, tmpmount, tmproot);
370371
cg_infos[CPUACCT_IDX]._data_complete = true;
371372
} else if (strcmp(token, "pids") == 0) {
372373
any_cgroup_mounts_found = true;
373-
assert(cg_infos[PIDS_IDX]._mount_path == NULL, "stomping of _mount_path");
374-
cg_infos[PIDS_IDX]._mount_path = os::strdup(tmpmount);
375-
cg_infos[PIDS_IDX]._root_mount_path = os::strdup(tmproot);
374+
set_controller_paths(cg_infos, PIDS_IDX, token, tmpmount, tmproot);
376375
cg_infos[PIDS_IDX]._data_complete = true;
377376
}
378377
}

src/hotspot/os/linux/cgroupSubsystem_linux.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,11 @@ class CgroupSubsystemFactory: AllStatic {
311311
}
312312
#endif
313313

314+
static void set_controller_paths(CgroupInfo* cg_infos,
315+
int controller,
316+
const char* name,
317+
char* mount_path,
318+
char* root_path);
314319
// Determine the cgroup type (version 1 or version 2), given
315320
// relevant paths to files. Sets 'flags' accordingly.
316321
static bool determine_type(CgroupInfo* cg_infos,

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

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,19 @@ public class CgroupSubsystemFactory {
6262
private Path cgroupv1MntInfoZeroHierarchy;
6363
private Path cgroupv2CgInfoZeroHierarchy;
6464
private Path cgroupv2MntInfoZeroHierarchy;
65+
private Path cgroupv2MntInfoDouble;
66+
private Path cgroupv2MntInfoDouble2;
6567
private Path cgroupv1CgInfoNonZeroHierarchy;
6668
private Path cgroupv1MntInfoNonZeroHierarchyOtherOrder;
6769
private Path cgroupv1MntInfoNonZeroHierarchy;
6870
private Path cgroupv1MntInfoDoubleCpuset;
6971
private Path cgroupv1MntInfoDoubleCpuset2;
72+
private Path cgroupv1MntInfoDoubleMemory;
73+
private Path cgroupv1MntInfoDoubleMemory2;
74+
private Path cgroupv1MntInfoDoubleCpu;
75+
private Path cgroupv1MntInfoDoubleCpu2;
76+
private Path cgroupv1MntInfoDoublePids;
77+
private Path cgroupv1MntInfoDoublePids2;
7078
private Path cgroupv1MntInfoSystemdOnly;
7179
private String mntInfoEmpty = "";
7280
private Path cgroupV1SelfCgroup;
@@ -160,6 +168,15 @@ public class CgroupSubsystemFactory {
160168
private String mntInfoCgroupv1MoreCpusetLine = "121 32 0:37 / /cpusets rw,relatime shared:69 - cgroup none rw,cpuset\n";
161169
private String mntInfoCgroupv1DoubleCpuset = mntInfoCgroupv1MoreCpusetLine + mntInfoHybrid;
162170
private String mntInfoCgroupv1DoubleCpuset2 = mntInfoHybrid + mntInfoCgroupv1MoreCpusetLine;
171+
private String mntInfoCgroupv1MoreMemoryLine = "1100 1098 0:28 / /memory rw,nosuid,nodev,noexec,relatime master:6 - cgroup cgroup rw,memory\n";
172+
private String mntInfoCgroupv1DoubleMemory = mntInfoCgroupv1MoreMemoryLine + mntInfoHybrid;
173+
private String mntInfoCgroupv1DoubleMemory2 = mntInfoHybrid + mntInfoCgroupv1MoreMemoryLine;
174+
private String mntInfoCgroupv1DoubleCpuLine = "1101 1098 0:29 / /cpu,cpuacct rw,nosuid,nodev,noexec,relatime master:7 - cgroup cgroup rw,cpu,cpuacct\n";
175+
private String mntInfoCgroupv1DoubleCpu = mntInfoCgroupv1DoubleCpuLine + mntInfoHybrid;
176+
private String mntInfoCgroupv1DoubleCpu2 = mntInfoHybrid + mntInfoCgroupv1DoubleCpuLine;
177+
private String mntInfoCgroupv1DoublePidsLine = "1107 1098 0:35 / /pids rw,nosuid,nodev,noexec,relatime master:13 - cgroup cgroup rw,pids\n";
178+
private String mntInfoCgroupv1DoublePids = mntInfoCgroupv1DoublePidsLine + mntInfoHybrid;
179+
private String mntInfoCgroupv1DoublePids2 = mntInfoHybrid + mntInfoCgroupv1DoublePidsLine;
163180
private String cgroupsNonZeroHierarchy =
164181
"#subsys_name hierarchy num_cgroups enabled\n" +
165182
"cpuset 3 1 1\n" +
@@ -175,7 +192,11 @@ public class CgroupSubsystemFactory {
175192
"hugetlb 6 1 1\n" +
176193
"pids 9 80 1"; // hierarchy has to match procSelfCgroupHybridContent
177194
private String mntInfoCgroupsV2Only =
178-
"28 21 0:25 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:4 - cgroup2 none rw,seclabel,nsdelegate";
195+
"28 21 0:25 / /sys/fs/cgroup rw,nosuid,nodev,noexec,relatime shared:4 - cgroup2 none rw,seclabel,nsdelegate\n";
196+
private String mntInfoCgroupsV2MoreLine =
197+
"240 232 0:24 /../.. /cgroup-in ro,relatime - cgroup2 cgroup2 rw,nsdelegate\n";
198+
private String mntInfoCgroupsV2Double = mntInfoCgroupsV2MoreLine + mntInfoCgroupsV2Only;
199+
private String mntInfoCgroupsV2Double2 = mntInfoCgroupsV2Only + mntInfoCgroupsV2MoreLine;
179200
private String mntInfoCgroupsV1SystemdOnly =
180201
"35 26 0:26 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime - cgroup systemd rw,name=systemd\n" +
181202
"26 18 0:19 / /sys/fs/cgroup rw,relatime - tmpfs none rw,size=4k,mode=755\n";
@@ -217,6 +238,12 @@ private void setup() {
217238
cgroupv2MntInfoZeroHierarchy = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv2");
218239
Files.writeString(cgroupv2MntInfoZeroHierarchy, mntInfoCgroupsV2Only);
219240

241+
cgroupv2MntInfoDouble = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv2_double");
242+
Files.writeString(cgroupv2MntInfoDouble, mntInfoCgroupsV2Double);
243+
244+
cgroupv2MntInfoDouble2 = Paths.get(existingDirectory.toString(), "mountinfo_cgroupv2_double2");
245+
Files.writeString(cgroupv2MntInfoDouble2, mntInfoCgroupsV2Double2);
246+
220247
cgroupv1CgInfoNonZeroHierarchy = Paths.get(existingDirectory.toString(), "cgroups_non_zero");
221248
Files.writeString(cgroupv1CgInfoNonZeroHierarchy, cgroupsNonZeroHierarchy);
222249

@@ -244,6 +271,24 @@ private void setup() {
244271
cgroupv1MntInfoDoubleCpuset2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_cpuset2");
245272
Files.writeString(cgroupv1MntInfoDoubleCpuset2, mntInfoCgroupv1DoubleCpuset2);
246273

274+
cgroupv1MntInfoDoubleMemory = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_memory");
275+
Files.writeString(cgroupv1MntInfoDoubleMemory, mntInfoCgroupv1DoubleMemory);
276+
277+
cgroupv1MntInfoDoubleMemory2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_memory2");
278+
Files.writeString(cgroupv1MntInfoDoubleMemory2, mntInfoCgroupv1DoubleMemory2);
279+
280+
cgroupv1MntInfoDoubleCpu = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_cpu");
281+
Files.writeString(cgroupv1MntInfoDoubleCpu, mntInfoCgroupv1DoubleCpu);
282+
283+
cgroupv1MntInfoDoubleCpu2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_cpu2");
284+
Files.writeString(cgroupv1MntInfoDoubleCpu2, mntInfoCgroupv1DoubleCpu2);
285+
286+
cgroupv1MntInfoDoublePids = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_pids");
287+
Files.writeString(cgroupv1MntInfoDoublePids, mntInfoCgroupv1DoublePids);
288+
289+
cgroupv1MntInfoDoublePids2 = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_double_pids2");
290+
Files.writeString(cgroupv1MntInfoDoublePids2, mntInfoCgroupv1DoublePids2);
291+
247292
cgroupv1MntInfoSystemdOnly = Paths.get(existingDirectory.toString(), "mnt_info_cgroupv1_systemd_only");
248293
Files.writeString(cgroupv1MntInfoSystemdOnly, mntInfoCgroupsV1SystemdOnly);
249294

@@ -291,14 +336,14 @@ public void testCgroupv1JoinControllerCombo(WhiteBox wb) {
291336
System.out.println("testCgroupv1JoinControllerMounts PASSED!");
292337
}
293338

294-
public void testCgroupv1MultipleCpusetMounts(WhiteBox wb, Path mountInfo) {
339+
public void testCgroupv1MultipleControllerMounts(WhiteBox wb, Path mountInfo) {
295340
String procCgroups = cgroupv1CgInfoNonZeroHierarchy.toString();
296341
String procSelfCgroup = cgroupV1SelfCgroup.toString();
297342
String procSelfMountinfo = mountInfo.toString();
298343
int retval = wb.validateCgroup(procCgroups, procSelfCgroup, procSelfMountinfo);
299-
Asserts.assertEQ(CGROUPS_V1, retval, "Multiple cpuset controllers, but only one in /sys/fs/cgroup");
344+
Asserts.assertEQ(CGROUPS_V1, retval, "Multiple controllers, but only one in /sys/fs/cgroup");
300345
Asserts.assertTrue(isValidCgroup(retval));
301-
System.out.println("testCgroupv1MultipleCpusetMounts PASSED!");
346+
System.out.println("testCgroupv1MultipleControllerMounts PASSED!");
302347
}
303348

304349
public void testCgroupv1SystemdOnly(WhiteBox wb) {
@@ -341,10 +386,10 @@ public void testCgroupv1MissingMemoryController(WhiteBox wb) {
341386
System.out.println("testCgroupv1MissingMemoryController PASSED!");
342387
}
343388

344-
public void testCgroupv2(WhiteBox wb) {
389+
public void testCgroupv2(WhiteBox wb, Path mountInfo) {
345390
String procCgroups = cgroupv2CgInfoZeroHierarchy.toString();
346391
String procSelfCgroup = cgroupV2SelfCgroup.toString();
347-
String procSelfMountinfo = cgroupv2MntInfoZeroHierarchy.toString();
392+
String procSelfMountinfo = mountInfo.toString();
348393
int retval = wb.validateCgroup(procCgroups, procSelfCgroup, procSelfMountinfo);
349394
Asserts.assertEQ(CGROUPS_V2, retval, "Expected");
350395
Asserts.assertTrue(isValidCgroup(retval));
@@ -388,13 +433,21 @@ public static void main(String[] args) throws Exception {
388433
try {
389434
test.testCgroupv1SystemdOnly(wb);
390435
test.testCgroupv1NoMounts(wb);
391-
test.testCgroupv2(wb);
436+
test.testCgroupv2(wb, test.cgroupv2MntInfoZeroHierarchy);
437+
test.testCgroupv2(wb, test.cgroupv2MntInfoDouble);
438+
test.testCgroupv2(wb, test.cgroupv2MntInfoDouble2);
392439
test.testCgroupV1Hybrid(wb);
393440
test.testCgroupV1HybridMntInfoOrder(wb);
394441
test.testCgroupv1MissingMemoryController(wb);
395442
test.testCgroupv2NoCgroup2Fs(wb);
396-
test.testCgroupv1MultipleCpusetMounts(wb, test.cgroupv1MntInfoDoubleCpuset);
397-
test.testCgroupv1MultipleCpusetMounts(wb, test.cgroupv1MntInfoDoubleCpuset2);
443+
test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleCpuset);
444+
test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleCpuset2);
445+
test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleMemory);
446+
test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleMemory2);
447+
test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleCpu);
448+
test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoubleCpu2);
449+
test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoublePids);
450+
test.testCgroupv1MultipleControllerMounts(wb, test.cgroupv1MntInfoDoublePids2);
398451
test.testCgroupv1JoinControllerCombo(wb);
399452
test.testNonZeroHierarchyOnlyFreezer(wb);
400453
} finally {

test/hotspot/jtreg/containers/docker/DockerBasicTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ public static void main(String[] args) throws Exception {
5353
try {
5454
testJavaVersion();
5555
testHelloDocker();
56+
testJavaVersionWithCgMounts();
5657
} finally {
5758
if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) {
5859
DockerTestUtils.removeDockerImage(imageNameAndTag);
@@ -81,4 +82,17 @@ private static void testHelloDocker() throws Exception {
8182
.shouldHaveExitValue(0)
8283
.shouldContain("Hello Docker");
8384
}
85+
86+
87+
private static void testJavaVersionWithCgMounts() throws Exception {
88+
DockerRunOptions opts =
89+
new DockerRunOptions(imageNameAndTag, "/jdk/bin/java", "-version")
90+
.addDockerOpts("-v", "/sys/fs/cgroup:/cgroups-in:ro");
91+
92+
// Duplicated cgroup mounts should be handled by the container detection
93+
// code and should not cause any error/warning output.
94+
DockerTestUtils.dockerRunJava(opts)
95+
.shouldHaveExitValue(0)
96+
.shouldNotMatch("\\[os,container *\\]");
97+
}
8498
}

test/hotspot/jtreg/containers/docker/TestCPUAwareness.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,11 @@ public static void main(String[] args) throws Exception {
7070
testActiveProcessorCount(2, 2);
7171

7272
// cpu quota and period
73-
testCpuQuotaAndPeriod(50*1000, 100*1000);
74-
testCpuQuotaAndPeriod(100*1000, 100*1000);
75-
testCpuQuotaAndPeriod(150*1000, 100*1000);
76-
testCpuQuotaAndPeriod(400*1000, 100*1000);
73+
testCpuQuotaAndPeriod(50*1000, 100*1000, false);
74+
testCpuQuotaAndPeriod(100*1000, 100*1000, false);
75+
testCpuQuotaAndPeriod(150*1000, 100*1000, false);
76+
testCpuQuotaAndPeriod(400*1000, 100*1000, false);
77+
testCpuQuotaAndPeriod(50*1000, 100*1000, true /* additional cgroup mount */);
7778

7879
testOperatingSystemMXBeanAwareness("0.5", "1");
7980
testOperatingSystemMXBeanAwareness("1.0", "1");
@@ -153,7 +154,7 @@ private static int adjustExpectedAPCForAvailableCPUs(int expectedAPC) {
153154
}
154155

155156

156-
private static void testCpuQuotaAndPeriod(int quota, int period)
157+
private static void testCpuQuotaAndPeriod(int quota, int period, boolean addCgmounts)
157158
throws Exception {
158159
Common.logNewTestCase("test cpu quota and period: ");
159160
System.out.println("quota = " + quota);
@@ -167,6 +168,10 @@ private static void testCpuQuotaAndPeriod(int quota, int period)
167168
.addDockerOpts("--cpu-period=" + period)
168169
.addDockerOpts("--cpu-quota=" + quota);
169170

171+
if (addCgmounts) {
172+
opts = opts.addDockerOpts("--volume", "/sys/fs/cgroup:/cgroups-in:ro");
173+
}
174+
170175
Common.run(opts)
171176
.shouldMatch("CPU Period is.*" + period)
172177
.shouldMatch("CPU Quota is.*" + quota)

0 commit comments

Comments
 (0)