This is an automated email from the ASF dual-hosted git repository.
adoroszlai pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new dd0dbc52182 HDDS-15038. Move container directory back to tmp when
container import is failed (#10199)
dd0dbc52182 is described below
commit dd0dbc521820dfdaec31d69c421cdd798d94bc5c
Author: Devesh Kumar Singh <[email protected]>
AuthorDate: Sat May 16 22:42:05 2026 +0530
HDDS-15038. Move container directory back to tmp when container import is
failed (#10199)
---
.../container/keyvalue/KeyValueContainer.java | 15 ++++-
.../container/keyvalue/TestKeyValueContainer.java | 65 ++++++++++++++++++++++
2 files changed, 77 insertions(+), 3 deletions(-)
diff --git
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java
index b8214882f12..5be6d20a336 100644
---
a/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java
+++
b/hadoop-hdds/container-service/src/main/java/org/apache/hadoop/ozone/container/keyvalue/KeyValueContainer.java
@@ -664,15 +664,24 @@ private void cleanupFailedImport() {
if (containerData.hasSchema(OzoneConsts.SCHEMA_V3)) {
BlockUtils.removeContainerFromDB(containerData, config);
}
- FileUtils.deleteDirectory(new File(containerData.getMetadataPath()));
- FileUtils.deleteDirectory(new File(containerData.getChunksPath()));
- FileUtils.deleteDirectory(new
File(getContainerData().getContainerPath()));
+ File containerDir = new File(getContainerData().getContainerPath());
+ if (containerDir.exists()) {
+ KeyValueContainerUtil.moveToDeletedContainerDir(containerData,
+ containerData.getVolume());
+
deleteDirectory(KeyValueContainerUtil.getTmpDirectoryPath(containerData,
+ containerData.getVolume()).toFile());
+ }
} catch (Exception ex) {
LOG.error("Failed to cleanup destination directories for container {}",
containerData.getContainerID(), ex);
}
}
+ @VisibleForTesting
+ void deleteDirectory(File directory) throws IOException {
+ FileUtils.deleteDirectory(directory);
+ }
+
@Override
public void exportContainerData(OutputStream destination,
ContainerPacker<KeyValueContainerData> packer) throws IOException {
diff --git
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java
index 9e66aaeb067..37728cde4e0 100644
---
a/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java
+++
b/hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java
@@ -44,6 +44,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -79,6 +80,8 @@
import org.apache.hadoop.ozone.container.common.helpers.BlockData;
import org.apache.hadoop.ozone.container.common.impl.ContainerDataYaml;
import org.apache.hadoop.ozone.container.common.impl.ContainerLayoutVersion;
+import org.apache.hadoop.ozone.container.common.interfaces.Container;
+import org.apache.hadoop.ozone.container.common.interfaces.ContainerPacker;
import org.apache.hadoop.ozone.container.common.interfaces.DBHandle;
import
org.apache.hadoop.ozone.container.common.statemachine.DatanodeConfiguration;
import org.apache.hadoop.ozone.container.common.utils.DatanodeStoreCache;
@@ -492,6 +495,68 @@ public void
testContainerImportExport(ContainerTestVersionInfo versionInfo)
}
}
+ @ContainerTestVersionInfo.ContainerTest
+ public void testFailedImportCleanupMovesContainerBeforeDelete(
+ ContainerTestVersionInfo versionInfo) throws Exception {
+ init(versionInfo);
+
+ HddsVolume containerVolume = volumeChoosingPolicy.chooseVolume(
+ StorageVolumeUtil.getHddsVolumesList(volumeSet.getVolumesList()), 1);
+
+ KeyValueContainer container = new KeyValueContainer(
+ keyValueContainerData, CONF) {
+ @Override
+ void deleteDirectory(File directory) throws IOException {
+ File deletedContainerDir = KeyValueContainerUtil.getTmpDirectoryPath(
+ getContainerData(), getContainerData().getVolume()).toFile();
+ if (directory.equals(deletedContainerDir)) {
+ throw new IOException("Injected tmp cleanup failure");
+ }
+ super.deleteDirectory(directory);
+ }
+ };
+ container.populatePathFields(scmId, containerVolume);
+
+ ContainerPacker<KeyValueContainerData> failingPacker =
+ new ContainerPacker<KeyValueContainerData>() {
+ @Override
+ public byte[] unpackContainerData(
+ Container<KeyValueContainerData> containerToUnpack,
+ InputStream inputStream, Path tmpDir, Path destContainerDir)
+ throws IOException {
+ Files.createDirectories(new File(containerToUnpack
+ .getContainerData().getChunksPath()).toPath());
+ Files.createDirectories(new File(containerToUnpack
+ .getContainerData().getMetadataPath()).toPath());
+ throw new IOException("Injected import failure");
+ }
+
+ @Override
+ public void pack(Container<KeyValueContainerData> containerToPack,
+ OutputStream destination) {
+ }
+
+ @Override
+ public byte[] unpackContainerDescriptor(InputStream inputStream) {
+ return null;
+ }
+ };
+
+ assertThrows(IOException.class, () -> container.importContainerData(
+ new ByteArrayInputStream(new byte[0]), failingPacker));
+
+ assertThat(new File(container.getContainerData().getContainerPath()))
+ .doesNotExist();
+ File deletedContainerDir = KeyValueContainerUtil.getTmpDirectoryPath(
+ container.getContainerData(), container.getContainerData().getVolume())
+ .toFile();
+ assertThat(deletedContainerDir).exists();
+ assertThat(new File(deletedContainerDir, OzoneConsts.STORAGE_DIR_CHUNKS))
+ .exists();
+ assertThat(new File(deletedContainerDir, OzoneConsts.CONTAINER_META_PATH))
+ .exists();
+ }
+
private void checkContainerFilesPresent(KeyValueContainerData data,
long expectedNumFilesInChunksDir) throws IOException {
File chunksDir = new File(data.getChunksPath());
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]