Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 021a35e

Browse files
Ekaterina VergizovaYuri Nesterenko
authored andcommitted
8242480: Negative value may be returned by getFreeSwapSpaceSize() in the docker
Backport-of: f6f97ea
1 parent 18bd8e2 commit 021a35e

File tree

3 files changed

+124
-2
lines changed

3 files changed

+124
-2
lines changed

src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ public long getFreeSwapSpaceSize() {
7272
if (containerMetrics != null) {
7373
long memSwapLimit = containerMetrics.getMemoryAndSwapLimit();
7474
long memLimit = containerMetrics.getMemoryLimit();
75+
long deltaLimit = memSwapLimit - memLimit;
76+
// Return 0 when memSwapLimit == memLimit, which means no swap space is allowed.
77+
// And the same for memSwapLimit < memLimit.
78+
if (deltaLimit <= 0) {
79+
return 0;
80+
}
7581
if (memSwapLimit >= 0 && memLimit >= 0) {
7682
for (int attempt = 0; attempt < MAX_ATTEMPTS_NUMBER; attempt++) {
7783
long memSwapUsage = containerMetrics.getMemoryAndSwapUsage();
@@ -80,8 +86,12 @@ public long getFreeSwapSpaceSize() {
8086
// We read "memory usage" and "memory and swap usage" not atomically,
8187
// and it's possible to get the negative value when subtracting these two.
8288
// If this happens just retry the loop for a few iterations.
83-
if ((memSwapUsage - memUsage) >= 0) {
84-
return memSwapLimit - memLimit - (memSwapUsage - memUsage);
89+
long deltaUsage = memSwapUsage - memUsage;
90+
if (deltaUsage >= 0) {
91+
long freeSwap = deltaLimit - deltaUsage;
92+
if (freeSwap >= 0) {
93+
return freeSwap;
94+
}
8595
}
8696
}
8797
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import com.sun.management.OperatingSystemMXBean;
25+
import java.lang.management.ManagementFactory;
26+
27+
public class GetFreeSwapSpaceSize {
28+
public static void main(String[] args) {
29+
System.out.println("TestGetFreeSwapSpaceSize");
30+
OperatingSystemMXBean osBean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
31+
for (int i = 0; i < 100; i++) {
32+
long size = osBean.getFreeSwapSpaceSize();
33+
if (size < 0) {
34+
System.out.println("Error: getFreeSwapSpaceSize returns " + size);
35+
System.exit(-1);
36+
}
37+
}
38+
}
39+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8242480
27+
* @requires docker.support
28+
* @library /test/lib
29+
* @build GetFreeSwapSpaceSize
30+
* @run driver TestGetFreeSwapSpaceSize
31+
*/
32+
import jdk.test.lib.containers.docker.Common;
33+
import jdk.test.lib.containers.docker.DockerRunOptions;
34+
import jdk.test.lib.containers.docker.DockerTestUtils;
35+
import jdk.test.lib.process.OutputAnalyzer;
36+
37+
public class TestGetFreeSwapSpaceSize {
38+
private static final String imageName = Common.imageName("memory");
39+
40+
public static void main(String[] args) throws Exception {
41+
if (!DockerTestUtils.canTestDocker()) {
42+
return;
43+
}
44+
45+
DockerTestUtils.buildJdkDockerImage(imageName, "Dockerfile-BasicTest", "jdk-docker");
46+
47+
try {
48+
testGetFreeSwapSpaceSize(
49+
"150M", Integer.toString(((int) Math.pow(2, 20)) * 150),
50+
"150M", Integer.toString(0)
51+
);
52+
} finally {
53+
if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) {
54+
DockerTestUtils.removeDockerImage(imageName);
55+
}
56+
}
57+
}
58+
59+
private static void testGetFreeSwapSpaceSize(String memoryAllocation, String expectedMemory,
60+
String swapAllocation, String expectedSwap) throws Exception {
61+
Common.logNewTestCase("TestGetFreeSwapSpaceSize");
62+
63+
DockerRunOptions opts = Common.newOpts(imageName, "GetFreeSwapSpaceSize")
64+
.addDockerOpts(
65+
"--memory", memoryAllocation,
66+
"--memory-swap", swapAllocation
67+
);
68+
69+
OutputAnalyzer out = DockerTestUtils.dockerRunJava(opts);
70+
out.shouldHaveExitValue(0)
71+
.shouldContain("TestGetFreeSwapSpaceSize");
72+
}
73+
}

0 commit comments

Comments
 (0)