This is an automated email from the ASF dual-hosted git repository.

sshenoy 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 94a401415fa HDDS-14654. NoSuchFileException when orphan check runs 
after purged snapshot YAML is deleted. (#9786)
94a401415fa is described below

commit 94a401415fa6ac43450eb0d5d460f66f0405cd59
Author: Sadanand Shenoy <[email protected]>
AuthorDate: Mon Mar 2 21:38:35 2026 +0530

    HDDS-14654. NoSuchFileException when orphan check runs after purged 
snapshot YAML is deleted. (#9786)
---
 .../om/snapshot/OmSnapshotLocalDataManager.java    |  4 ++-
 .../snapshot/TestOmSnapshotLocalDataManager.java   | 34 ++++++++++++++++++++++
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java
 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java
index cec65701c80..d542932909c 100644
--- 
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/snapshot/OmSnapshotLocalDataManager.java
@@ -947,7 +947,9 @@ private void checkForOphanVersionsAndIncrementCount(UUID 
snapshotId, SnapshotVer
         // become an orphan. Otherwise if the version is updated it
         // could mean that there could be some orphan version present within 
the
         // same snapshot.
-        if (isPurgeTransactionSet || previousVersionsMeta.getVersion() != 
currentVersionMeta.getVersion()) {
+        // Do not increment for snapshotId when the YAML was just deleted 
(empty versions).
+        if (!currentVersionMeta.getSnapshotVersions().isEmpty() &&
+                (isPurgeTransactionSet || previousVersionsMeta.getVersion() != 
currentVersionMeta.getVersion())) {
           incrementOrphanCheckCount(snapshotId);
         }
       }
diff --git 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java
 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java
index f9d8fba45a8..a2884af7646 100644
--- 
a/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java
+++ 
b/hadoop-ozone/ozone-manager/src/test/java/org/apache/hadoop/ozone/om/snapshot/TestOmSnapshotLocalDataManager.java
@@ -1150,4 +1150,38 @@ private void writeLocalDataToFile(OmSnapshotLocalData 
localData, Path filePath)
     // you would use the YamlSerializer
     snapshotLocalDataYamlSerializer.save(filePath.toFile(), localData);
   }
+
+  /**
+   * Tests the fix for the NoSuchFileException : when a purged snapshot (last 
in chain)
+   * has all its versions removed and YAML deleted by orphan check, it must 
NOT be
+   * re-added to snapshotToBeCheckedForOrphans. Otherwise the next orphan 
check run
+   * would try to load the deleted YAML and throw NoSuchFileException.
+   *
+   */
+  @Test
+  public void testPurgedSnapshotNotReAddedAfterYamlDeleted() throws Exception {
+    localDataManager = getNewOmSnapshotLocalDataManager();
+    List<UUID> snapshotIds = createSnapshotLocalData(localDataManager, 2);
+    UUID secondSnapId = snapshotIds.get(1);
+    // Simulate purge: set transactionInfo on S2's YAML (purge does this 
before orphan check runs)
+    try (WritableOmSnapshotLocalDataProvider writableProvider =
+             localDataManager.getWritableOmSnapshotLocalData(secondSnapId)) {
+      writableProvider.setTransactionInfo(TransactionInfo.valueOf(1, 1));
+      writableProvider.commit();
+    }
+    // S2 is last in chain - mark as purged so all versions get removed
+    purgedSnapshotIdMap.put(secondSnapId, true);
+    // Simulate purge adding S2 to orphan check list
+    localDataManager.getSnapshotToBeCheckedForOrphans().clear();
+    localDataManager.getSnapshotToBeCheckedForOrphans().put(secondSnapId, 1);
+    // Run full orphan check
+    java.lang.reflect.Method method = 
OmSnapshotLocalDataManager.class.getDeclaredMethod(
+        "checkOrphanSnapshotVersions", OMMetadataManager.class,
+        org.apache.hadoop.ozone.om.SnapshotChainManager.class);
+    method.setAccessible(true);
+    method.invoke(localDataManager, omMetadataManager, null);
+    // S2 should NOT be in the map
+    
assertFalse(localDataManager.getSnapshotToBeCheckedForOrphans().containsKey(secondSnapId),
+        "Purged snapshot should not be re-added after YAML deleted");
+  }
 }


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

Reply via email to