Skip to content

Commit 9649e0e

Browse files
authored
HDDS-14888. Improve DiskCheckUtil.checkReadWrite to tolerate disk full (#9972)
1 parent f9552d0 commit 9649e0e

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/common/utils/DiskCheckUtil.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
* where the disk is mounted.
4343
*/
4444
public final class DiskCheckUtil {
45+
public static final String LINUX_DISK_FULL_MESSAGE = "No space left on device";
4546
// For testing purposes, an alternate check implementation can be provided
4647
// to inject failures.
4748
private static DiskChecks impl = new DiskChecksImpl();
@@ -149,10 +150,15 @@ public boolean checkReadWrite(File storageDir,
149150
"volume check.", testFile.getAbsolutePath()), notFoundEx);
150151
return false;
151152
} catch (SyncFailedException syncEx) {
152-
logError(storageDir, String.format("Could sync file %s to disk.",
153+
logError(storageDir, String.format("Could not sync file %s to disk.",
153154
testFile.getAbsolutePath()), syncEx);
154155
return false;
155156
} catch (IOException ioEx) {
157+
String msg = ioEx.getMessage();
158+
if (msg != null && msg.contains(LINUX_DISK_FULL_MESSAGE)) {
159+
LOG.warn("Could not write file {} for volume check", testFile.getAbsolutePath(), ioEx);
160+
return true;
161+
}
156162
logError(storageDir, String.format("Could not write file %s " +
157163
"for volume check.", testFile.getAbsolutePath()), ioEx);
158164
return false;

hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/common/utils/TestDiskCheckUtil.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,28 @@
2020
import static org.junit.jupiter.api.Assertions.assertEquals;
2121
import static org.junit.jupiter.api.Assertions.assertFalse;
2222
import static org.junit.jupiter.api.Assertions.assertNotNull;
23+
import static org.junit.jupiter.api.Assertions.assertThrows;
2324
import static org.junit.jupiter.api.Assertions.assertTrue;
25+
import static org.mockito.ArgumentMatchers.any;
26+
import static org.mockito.Mockito.mockStatic;
2427

2528
import java.io.File;
29+
import java.nio.file.FileSystemException;
30+
import java.nio.file.OpenOption;
31+
import org.apache.ratis.util.FileUtils;
2632
import org.junit.jupiter.api.Test;
2733
import org.junit.jupiter.api.io.TempDir;
34+
import org.junit.jupiter.api.parallel.Execution;
35+
import org.junit.jupiter.api.parallel.ExecutionMode;
36+
import org.mockito.MockedStatic;
2837

2938
/**
3039
* Tests {@link DiskCheckUtil} does not incorrectly identify an unhealthy
3140
* disk or mount point.
3241
* Tests that it identifies an improperly configured directory mount point.
3342
*
3443
*/
44+
@Execution(ExecutionMode.SAME_THREAD)
3545
public class TestDiskCheckUtil {
3646

3747
@TempDir
@@ -80,4 +90,21 @@ public void testReadWrite() {
8090
assertNotNull(children);
8191
assertEquals(0, children.length);
8292
}
93+
94+
@Test
95+
public void testCheckReadWriteDiskFull() {
96+
try (MockedStatic<FileUtils> mockService = mockStatic(FileUtils.class)) {
97+
// fos.write(writtenBytes) also through FileSystemException with the message
98+
mockService.when(() -> FileUtils.newOutputStreamForceAtClose(any(File.class), any(OpenOption[].class)))
99+
.thenThrow(new FileSystemException("No space left on device"));
100+
101+
String path = testDir.getAbsolutePath();
102+
assertThrows(FileSystemException.class,
103+
() -> FileUtils.newOutputStreamForceAtClose(new File(path), new OpenOption[2]));
104+
105+
// Test that checkReadWrite returns true for the disk full case
106+
boolean result = DiskCheckUtil.checkReadWrite(testDir, testDir, 1024);
107+
assertTrue(result, "checkReadWrite should return true when disk is full");
108+
}
109+
}
83110
}

0 commit comments

Comments
 (0)