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]