Copilot commented on code in PR #10199:
URL: https://github.com/apache/ozone/pull/10199#discussion_r3216177800


##########
hadoop-hdds/container-service/src/test/java/org/apache/hadoop/ozone/container/keyvalue/TestKeyValueContainer.java:
##########
@@ -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));
+
+    assertFalse(new File(container.getContainerData().getContainerPath())
+        .exists());
+    File deletedContainerDir = KeyValueContainerUtil.getTmpDirectoryPath(
+        container.getContainerData(), container.getContainerData().getVolume())
+        .toFile();
+    assertTrue(deletedContainerDir.exists());
+    assertTrue(new File(deletedContainerDir, OzoneConsts.STORAGE_DIR_CHUNKS)
+        .exists());
+    assertTrue(new File(deletedContainerDir, OzoneConsts.CONTAINER_META_PATH)
+        .exists());

Review Comment:
   This test currently injects a failure when deleting the deleted-container 
tmp directory and then asserts that both chunks/ and metadata/ still exist 
under that directory. That doesn’t validate the PR’s stated goal (clean up 
chunks/ before metadata/ so that, on partial cleanup, metadata remains but 
chunks is gone). To cover the intended behavior, inject the failure at metadata 
deletion (or immediately after chunks deletion) and assert that chunks/ has 
been removed while metadata/ is still present.



##########
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());

Review Comment:
   cleanupFailedImport now moves the container dir to the deleted-container 
area and then calls FileUtils.deleteDirectory on the whole directory. This does 
not guarantee that chunks/ is deleted before metadata/ (Commons IO recursion 
order depends on File.listFiles ordering), so an interrupted/partial delete can 
still leave a chunks/-only residue—exactly the diagnostic issue this change is 
meant to avoid. Consider explicitly deleting the chunks directory first and the 
metadata directory second (then the container dir) in the deleted-container 
location, so partial cleanup preferentially preserves metadata.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to