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

sammichen pushed a commit to branch HDDS-7593
in repository https://gitbox.apache.org/repos/asf/ozone.git


The following commit(s) were added to refs/heads/HDDS-7593 by this push:
     new d993dffda6 HDDS-10774. Show deleted hsync keys in ListOpenFile CLI. 
(#6628)
d993dffda6 is described below

commit d993dffda609aeb10ba3a91575a227f737b0d580
Author: Ashish Kumar <[email protected]>
AuthorDate: Thu May 9 05:47:35 2024 +0530

    HDDS-10774. Show deleted hsync keys in ListOpenFile CLI. (#6628)
---
 .../hadoop/ozone/shell/TestOzoneShellHA.java       | 122 ++++++++++++++++++++-
 .../ozone/admin/om/ListOpenFilesSubCommand.java    |  21 +++-
 2 files changed, 140 insertions(+), 3 deletions(-)

diff --git 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
index 085858f711..aa4d851678 100644
--- 
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
+++ 
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/ozone/shell/TestOzoneShellHA.java
@@ -29,6 +29,7 @@ import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.TimeoutException;
 
 import org.apache.hadoop.fs.FSDataOutputStream;
 import org.apache.hadoop.crypto.key.KeyProvider;
@@ -51,6 +52,7 @@ import org.apache.hadoop.fs.ozone.OzoneFsShell;
 import org.apache.hadoop.hdds.conf.OzoneConfiguration;
 import org.apache.hadoop.ozone.MiniOzoneCluster;
 import org.apache.hadoop.ozone.MiniOzoneHAClusterImpl;
+import org.apache.hadoop.ozone.OzoneConsts;
 import org.apache.hadoop.ozone.client.ObjectStore;
 import org.apache.hadoop.ozone.client.OzoneBucket;
 import org.apache.hadoop.ozone.client.OzoneClient;
@@ -65,6 +67,7 @@ import org.apache.hadoop.ozone.om.OzoneManager;
 import org.apache.hadoop.ozone.om.exceptions.OMException;
 import org.apache.hadoop.ozone.om.helpers.BucketLayout;
 import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
+import org.apache.hadoop.ozone.om.service.OpenKeyCleanupService;
 import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.ozone.test.GenericTestUtils;
 import org.apache.hadoop.util.ToolRunner;
@@ -193,6 +196,7 @@ public class TestOzoneShellHA {
     final int numDNs = 5;
     conf.set(CommonConfigurationKeysPublic.HADOOP_SECURITY_KEY_PROVIDER_PATH,
         getKeyProviderURI(miniKMS));
+    conf.setInt(OMConfigKeys.OZONE_DIR_DELETING_SERVICE_INTERVAL, 10);
     conf.setBoolean(OMConfigKeys.OZONE_OM_ENABLE_FILESYSTEM_PATHS, true);
     MiniOzoneHAClusterImpl.Builder builder = 
MiniOzoneCluster.newHABuilder(conf);
     builder.setOMServiceId(omServiceId)
@@ -582,7 +586,7 @@ public class TestOzoneShellHA {
 
   @Test
   public void testAdminCmdListOpenFiles()
-      throws IOException, InterruptedException {
+      throws IOException, InterruptedException, TimeoutException {
 
     OzoneConfiguration conf = cluster.getConf();
     final String hostPrefix = OZONE_OFS_URI_SCHEME + "://" + omServiceId;
@@ -699,6 +703,122 @@ public class TestOzoneShellHA {
 
   }
 
+  @Test
+  public void testAdminCmdListOpenFilesWithDeletedKeys()
+      throws Exception {
+
+    OzoneConfiguration conf = cluster.getConf();
+    final String hostPrefix = OZONE_OFS_URI_SCHEME + "://" + omServiceId;
+
+    OzoneConfiguration clientConf = getClientConfForOFS(hostPrefix, conf);
+    clientConf.setBoolean(OZONE_FS_HSYNC_ENABLED, true);
+    FileSystem fs = FileSystem.get(clientConf);
+
+    assertNotEquals(fs.getConf().get(OZONE_FS_HSYNC_ENABLED),
+        "false", OZONE_FS_HSYNC_ENABLED + " is set to false " +
+            "by external force. Must be true to allow hsync to function");
+
+    final String volumeName = "volume-list-del";
+    final String bucketName = "buck1";
+
+    String dir1 = hostPrefix +
+        OM_KEY_PREFIX + volumeName +
+        OM_KEY_PREFIX + bucketName +
+        OM_KEY_PREFIX + "dir1";
+    // Create volume, bucket, dir
+    assertTrue(fs.mkdirs(new Path(dir1)));
+    String keyPrefix = OM_KEY_PREFIX + "key";
+
+    final int numKeys = 5;
+    String[] keys = new String[numKeys];
+
+    for (int i = 0; i < numKeys; i++) {
+      keys[i] = dir1 + keyPrefix + i;
+    }
+
+    String pathToBucket = "/" +  volumeName + "/" + bucketName;
+    FSDataOutputStream[] streams = new FSDataOutputStream[numKeys];
+
+    try {
+      // Create multiple keys and hold them open
+      for (int i = 0; i < numKeys; i++) {
+        streams[i] = fs.create(new Path(keys[i]));
+        streams[i].write(1);
+      }
+
+      // Wait for DB flush
+      cluster.getOzoneManager().awaitDoubleBufferFlush();
+
+      // hsync last key
+      streams[numKeys - 1].hsync();
+      // Wait for flush
+      cluster.getOzoneManager().awaitDoubleBufferFlush();
+      final String[] args = new String[] {"om", "lof", "--service-id",
+          omServiceId, "--show-deleted", "-p", pathToBucket};
+
+      execute(ozoneAdminShell, args);
+      String cmdRes = getStdOut();
+
+      // Verify that key is hsync'ed
+      assertTrue(cmdRes.contains("\tYes\t\tNo"), "key should be hsync'ed and 
not deleted");
+
+      // Verify json output
+      String[] args1 = new String[] {"om", "lof", "--service-id", omServiceId, 
"--show-deleted",
+          "--json", "-p", pathToBucket};
+      execute(ozoneAdminShell, args1);
+      cmdRes = getStdOut();
+
+      assertTrue(!cmdRes.contains(OzoneConsts.DELETED_HSYNC_KEY),
+          "key should not have deletedHsyncKey metadata");
+
+      // Suspend open key cleanup service so that key remains in openKeyTable 
for verification
+      OpenKeyCleanupService openKeyCleanupService =
+          (OpenKeyCleanupService) 
cluster.getOzoneManager().getKeyManager().getOpenKeyCleanupService();
+      openKeyCleanupService.suspend();
+      OzoneFsShell shell = new OzoneFsShell(clientConf);
+      // Delete directory dir1
+      ToolRunner.run(shell, new String[]{"-rm", "-R", "-skipTrash", dir1});
+
+      GenericTestUtils.waitFor(() -> {
+        try {
+          execute(ozoneAdminShell, args);
+          String cmdRes1 = getStdOut();
+          // When directory purge request is triggered it should add 
DELETED_HSYNC_KEY metadata in hsync openKey
+          // And list open key should show as deleted
+          return cmdRes1.contains("\tYes\t\tYes");
+        } catch (Throwable t) {
+          LOG.warn("Failed to list open key", t);
+          return false;
+        }
+      }, 1000, 10000);
+
+      // Now check json output
+      execute(ozoneAdminShell, args1);
+      cmdRes = getStdOut();
+      assertTrue(cmdRes.contains(OzoneConsts.DELETED_HSYNC_KEY),
+          "key should have deletedHsyncKey metadata");
+
+      // Verify result should not have deleted hsync keys when --show-deleted 
is not in the command argument
+      String[] args2 = new String[] {"om", "lof", "--service-id", omServiceId, 
"-p", pathToBucket};
+      execute(ozoneAdminShell, args2);
+      cmdRes = getStdOut();
+      // Verify that deletedHsyncKey is not in the result
+      assertTrue(!cmdRes.contains("\tYes\t\tYes"), "key should be hsync'ed and 
not deleted");
+
+      // Verify with json result
+      args2 = new String[] {"om", "lof", "--service-id", omServiceId, 
"--json", "-p", pathToBucket};
+      execute(ozoneAdminShell, args2);
+      cmdRes = getStdOut();
+      // Verify that deletedHsyncKey is not in the result
+      assertTrue(!cmdRes.contains(OzoneConsts.DELETED_HSYNC_KEY),
+          "key should not have deletedHsyncKey metadata");
+
+    }  finally {
+      // Cleanup
+      IOUtils.closeQuietly(streams);
+    }
+  }
+
   /**
    * Return stdout as a String, then clears existing output.
    */
diff --git 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/om/ListOpenFilesSubCommand.java
 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/om/ListOpenFilesSubCommand.java
index 9ede45a80a..90b064fce6 100644
--- 
a/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/om/ListOpenFilesSubCommand.java
+++ 
b/hadoop-ozone/tools/src/main/java/org/apache/hadoop/ozone/admin/om/ListOpenFilesSubCommand.java
@@ -66,6 +66,11 @@ public class ListOpenFilesSubCommand implements 
Callable<Void> {
       description = "Format output as JSON")
   private boolean json;
 
+  @CommandLine.Option(names = { "--show-deleted" },
+      defaultValue = "false",
+      description = "Whether to show deleted open keys")
+  private boolean showDeleted;
+
   // Conforms to ListOptions, but not all in ListOptions applies here thus
   // not using that directly
   @CommandLine.Option(
@@ -105,6 +110,9 @@ public class ListOpenFilesSubCommand implements 
Callable<Void> {
     ListOpenFilesResult res =
         ozoneManagerClient.listOpenFiles(pathPrefix, limit, startItem);
 
+    if (!showDeleted) {
+      res.getOpenKeys().removeIf(o -> 
o.getKeyInfo().getMetadata().containsKey(OzoneConsts.DELETED_HSYNC_KEY));
+    }
     if (json) {
       // Print detailed JSON
       printOpenKeysListAsJson(res);
@@ -132,7 +140,8 @@ public class ListOpenFilesSubCommand implements 
Callable<Void> {
     if (startItem != null && !startItem.isEmpty()) {
       msg += "\nafter continuation token:\n  " + startItem;
     }
-    msg += "\n\nClient ID\t\tCreation time\tHsync'ed\tOpen File Path";
+    msg += showDeleted ? "\n\nClient ID\t\tCreation 
time\tHsync'ed\tDeleted\t\tOpen File Path" :
+        "\n\nClient ID\t\tCreation time\tHsync'ed\tOpen File Path";
     System.out.println(msg);
 
     for (OpenKeySession e : openFileList) {
@@ -151,8 +160,16 @@ public class ListOpenFilesSubCommand implements 
Callable<Void> {
           // initially opens the file (!)
           line += "Yes w/ cid " + hsyncClientIdStr + "\t";
         }
+
+        if (showDeleted) {
+          if 
(omKeyInfo.getMetadata().containsKey(OzoneConsts.DELETED_HSYNC_KEY)) {
+            line += "Yes\t\t";
+          } else {
+            line += "No\t\t";
+          }
+        }
       } else {
-        line += "No\t\t";
+        line += showDeleted ? "No\t\tNo\t\t" : "No\t\t";
       }
 
       line += getFullPathFromKeyInfo(omKeyInfo);


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

Reply via email to