This is an automated email from the ASF dual-hosted git repository.
szetszwo 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 b97d943d5c HDDS-8436. Support setSafeMode(), isFileClosed() FileSystem
API (#4825)
b97d943d5c is described below
commit b97d943d5cee11933d4aed0665607c97c9be92ce
Author: Wei-Chiu Chuang <[email protected]>
AuthorDate: Wed Jul 5 03:29:51 2023 -0700
HDDS-8436. Support setSafeMode(), isFileClosed() FileSystem API (#4825)
---
.../main/java/org/apache/hadoop/ozone/OmUtils.java | 1 +
.../ozone/om/protocol/OzoneManagerProtocol.java | 15 ++++++
...OzoneManagerProtocolClientSideTranslatorPB.java | 36 ++++++++++++++
.../apache/hadoop/fs/ozone/TestLeaseRecovery.java | 3 ++
.../fs/ozone/TestOzoneFileSystemWithFSO.java | 27 ++++++++++
.../hadoop/fs/ozone/TestRootedOzoneFileSystem.java | 17 +++++++
.../fs/ozone/TestRootedOzoneFileSystemWithFSO.java | 27 ++++++++--
.../src/main/proto/OmClientProtocol.proto | 20 +++++++-
.../org/apache/hadoop/ozone/om/OzoneManager.java | 21 ++++++++
.../protocolPB/OzoneManagerRequestHandler.java | 33 +++++++++++++
.../org/apache/hadoop/fs/LeaseRecoverable.java | 52 ++++++++++++++++++++
.../main/java/org/apache/hadoop/fs/SafeMode.java | 57 ++++++++++++++++++++++
.../java/org/apache/hadoop/fs/SafeModeAction.java | 44 +++++++++++++++++
.../fs/ozone/BasicOzoneClientAdapterImpl.java | 32 ++++++++++++
.../hadoop/fs/ozone/BasicOzoneFileSystem.java | 13 +++++
.../ozone/BasicRootedOzoneClientAdapterImpl.java | 38 ++++++++++++++-
.../fs/ozone/BasicRootedOzoneFileSystem.java | 24 ++++-----
.../apache/hadoop/fs/ozone/OzoneClientAdapter.java | 8 +++
.../apache/hadoop/fs/ozone/OzoneClientUtils.java | 1 -
.../java/org/apache/hadoop/fs/ozone/Statistic.java | 8 ++-
.../java/org/apache/hadoop/fs/package-info.java | 30 ++++++++++++
.../apache/hadoop/fs/ozone/OzoneFileSystem.java | 27 +++++++++-
.../hadoop/fs/ozone/RootedOzoneFileSystem.java | 38 ++++++++++++++-
.../apache/hadoop/fs/ozone/OzoneFileSystem.java | 27 +++++++++-
.../hadoop/fs/ozone/RootedOzoneFileSystem.java | 29 ++++++++++-
25 files changed, 603 insertions(+), 25 deletions(-)
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
index 4cb3c678c0..1ae3842e1f 100644
--- a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
+++ b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/OmUtils.java
@@ -269,6 +269,7 @@ public final class OmUtils {
case CancelSnapshotDiff:
case ListSnapshotDiffJobs:
case TransferLeadership:
+ case SetSafeMode:
return true;
case CreateVolume:
case SetVolumeProperty:
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
index f02af22e21..da9e45ebc3 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocol/OzoneManagerProtocol.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.util.List;
import java.util.UUID;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.hdds.scm.container.common.helpers.ExcludeList;
import org.apache.hadoop.ozone.OzoneAcl;
import org.apache.hadoop.ozone.om.IOmMetadataReader;
@@ -1054,4 +1055,18 @@ public interface OzoneManagerProtocol
throws IOException;
UUID refetchSecretKey() throws IOException;
+ /**
+ * Enter, leave, or get safe mode.
+ *
+ * @param action One of {@link SafeModeAction} LEAVE, ENTER, GET,
+ * FORCE_EXIT.
+ * @param isChecked If true check only for Active metadata node /
+ * NameNode's status, else check first metadata node /
+ * NameNode's status.
+ * @throws IOException if set safe mode fails to proceed.
+ * @return true if the action is successfully accepted, otherwise false
+ * means rejected.
+ */
+ boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException;
}
diff --git
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
index c009028c46..2c0aef893b 100644
---
a/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
+++
b/hadoop-ozone/common/src/main/java/org/apache/hadoop/ozone/om/protocolPB/OzoneManagerProtocolClientSideTranslatorPB.java
@@ -26,6 +26,7 @@ import java.util.UUID;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.client.ECReplicationConfig;
import org.apache.hadoop.hdds.client.ReplicationConfig;
@@ -169,6 +170,7 @@ import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RenameK
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RenewDelegationTokenResponseProto;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RevokeS3SecretRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.S3Secret;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SafeMode;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetAclRequest;
@@ -176,6 +178,8 @@ import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetAclR
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetBucketPropertyRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetS3SecretRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetS3SecretResponse;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetSafeModeRequest;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetSafeModeResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetTimesRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetVolumePropertyRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantAssignAdminRequest;
@@ -2331,6 +2335,38 @@ public final class
OzoneManagerProtocolClientSideTranslatorPB
handleError(submitRequest(omRequest));
}
+ @Override
+ public boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException {
+ SetSafeModeRequest setSafeModeRequest =
+ SetSafeModeRequest.newBuilder()
+ .setSafeMode(toProtoBuf(action))
+ .build();
+
+ OMRequest omRequest = createOMRequest(Type.SetSafeMode)
+ .setSetSafeModeRequest(setSafeModeRequest).build();
+
+ SetSafeModeResponse setSafeModeResponse =
+ handleError(submitRequest(omRequest)).getSetSafeModeResponse();
+ return setSafeModeResponse.getResponse();
+ }
+
+ private SafeMode toProtoBuf(SafeModeAction action) {
+ switch (action) {
+ case ENTER:
+ return SafeMode.ENTER;
+ case LEAVE:
+ return SafeMode.LEAVE;
+ case FORCE_EXIT:
+ return SafeMode.FORCE_EXIT;
+ case GET:
+ return SafeMode.GET;
+ default:
+ throw new IllegalArgumentException("Unsupported safe mode action " +
+ action);
+ }
+ }
+
@VisibleForTesting
public OmTransport getTransport() {
return transport;
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestLeaseRecovery.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestLeaseRecovery.java
index a67db81ad8..fba842799c 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestLeaseRecovery.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestLeaseRecovery.java
@@ -48,6 +48,7 @@ import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_ADDRESS_KEY;
import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_RATIS_ENABLE_KEY;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
@@ -120,6 +121,7 @@ public class TestLeaseRecovery {
ThreadLocalRandom.current().nextBytes(data);
stream.write(data);
stream.hsync();
+ assertFalse(fs.isFileClosed(file));
int count = 0;
while (count++ < 15 && !fs.recoverLease(file)) {
@@ -127,6 +129,7 @@ public class TestLeaseRecovery {
}
// The lease should have been recovered.
assertTrue("File should be closed", fs.recoverLease(file));
+ assertTrue(fs.isFileClosed(file));
// open it again, make sure the data is correct
byte[] readData = new byte[1 << 20];
try (FSDataInputStream fdis = fs.open(file)) {
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFileSystemWithFSO.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFileSystemWithFSO.java
index 8ed595187b..ed148bc45f 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFileSystemWithFSO.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestOzoneFileSystemWithFSO.java
@@ -20,12 +20,14 @@ package org.apache.hadoop.fs.ozone;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.LeaseRecoverable;
import org.apache.hadoop.fs.LocatedFileStatus;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.RemoteIterator;
import org.apache.hadoop.fs.contract.ContractTestUtils;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.om.OMMetadataManager;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.helpers.BucketLayout;
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
import org.apache.hadoop.ozone.om.helpers.OmDirectoryInfo;
@@ -48,7 +50,9 @@ import java.util.Arrays;
import java.util.Collection;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -568,6 +572,29 @@ public class TestOzoneFileSystemWithFSO extends
TestOzoneFileSystem {
}, 1000, 120000);
}
+ /**
+ * Verify recoverLease() and isFileClosed() APIs.
+ * @throws Exception
+ */
+ @Test
+ public void testLeaseRecoverable() throws Exception {
+ // Create a file
+ Path parent = new Path("/d1/d2/");
+ Path source = new Path(parent, "file1");
+
+ LeaseRecoverable fs = (LeaseRecoverable)getFs();
+ FSDataOutputStream stream = getFs().create(source);
+ // file not visible yet
+ assertThrows(OMException.class, () -> fs.isFileClosed(source));
+ stream.write(1);
+ stream.hsync();
+ // file is visible and open
+ assertFalse(fs.isFileClosed(source));
+ assertTrue(fs.recoverLease(source));
+ // file is closed after lease recovery
+ assertTrue(fs.isFileClosed(source));
+ }
+
private void verifyOMFileInfoFormat(OmKeyInfo omKeyInfo, String fileName,
long parentID) {
Assert.assertEquals("Wrong keyName", fileName, omKeyInfo.getKeyName());
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystem.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystem.java
index 6f2be4b099..40b5433d11 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystem.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystem.java
@@ -30,6 +30,8 @@ import org.apache.hadoop.fs.InvalidPathException;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathIsNotEmptyDirectoryException;
import org.apache.hadoop.fs.RemoteIterator;
+import org.apache.hadoop.fs.SafeMode;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.fs.StreamCapabilities;
import org.apache.hadoop.fs.Trash;
import org.apache.hadoop.fs.TrashPolicy;
@@ -2545,4 +2547,19 @@ public class TestRootedOzoneFileSystem {
// verify that mtime is NOT updated as expected.
Assert.assertEquals(mtime, fileStatus.getModificationTime());
}
+
+ @Test
+ public void testSafeMode() throws Exception {
+ SafeMode safeModeFS = (SafeMode) fs;
+ // safe mode is off
+ assertFalse(safeModeFS.setSafeMode(SafeModeAction.GET));
+ // shutdown datanodes and restart SCM
+ cluster.shutdownHddsDatanodes();
+ cluster.restartStorageContainerManager(false);
+ // SCM should be in safe mode
+ assertTrue(safeModeFS.setSafeMode(SafeModeAction.GET));
+ // force exit safe mode and verify that it's out of safe mode.
+ safeModeFS.setSafeMode(SafeModeAction.FORCE_EXIT);
+ assertFalse(safeModeFS.setSafeMode(SafeModeAction.GET));
+ }
}
diff --git
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystemWithFSO.java
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystemWithFSO.java
index 1b78da7ce0..8a7c3c453b 100644
---
a/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystemWithFSO.java
+++
b/hadoop-ozone/integration-test/src/test/java/org/apache/hadoop/fs/ozone/TestRootedOzoneFileSystemWithFSO.java
@@ -19,8 +19,11 @@ package org.apache.hadoop.fs.ozone;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
+import org.apache.hadoop.fs.LeaseRecoverable;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.contract.ContractTestUtils;
+import org.apache.hadoop.ozone.om.exceptions.OMException;
+
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
@@ -36,6 +39,8 @@ import java.util.Collection;
import java.util.concurrent.TimeoutException;
import static org.apache.hadoop.ozone.OzoneConsts.OZONE_URI_DELIMITER;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
/**
@@ -128,13 +133,13 @@ public class TestRootedOzoneFileSystemWithFSO
+ root + "/b/c");
// rename should fail and return false
- Assert.assertFalse(getFs().rename(dir2SourcePath, destinPath));
+ assertFalse(getFs().rename(dir2SourcePath, destinPath));
// (b) parent of dst is a file. /root_dir/file1/c
Path filePath = new Path(getBucketPath() + root + "/file1");
ContractTestUtils.touch(getFs(), filePath);
Path newDestinPath = new Path(filePath, "c");
// rename should fail and return false
- Assert.assertFalse(getFs().rename(dir2SourcePath, newDestinPath));
+ assertFalse(getFs().rename(dir2SourcePath, newDestinPath));
}
@Test
@@ -188,7 +193,7 @@ public class TestRootedOzoneFileSystemWithFSO
LOG.info("Created dir1 {}", subDir1);
LOG.info("Rename op-> source:{} to destin:{}", sourceRoot, subDir1);
// rename should fail and return false
- Assert.assertFalse(getFs().rename(sourceRoot, subDir1));
+ assertFalse(getFs().rename(sourceRoot, subDir1));
} finally {
getFs().delete(sourceRoot, true);
}
@@ -265,4 +270,20 @@ public class TestRootedOzoneFileSystemWithFSO
Assert.assertEquals(valueGreaterBatchSize, fileStatuses.length);
}
+ @Test
+ public void testLeaseRecoverable() throws Exception {
+ // Create a file
+ final String dir = "dir1";
+ final String key = dir + "/key1";
+ final Path source = new Path(getBucketPath(), key);
+
+ LeaseRecoverable fs = (LeaseRecoverable)getFs();
+ FSDataOutputStream stream = getFs().create(source);
+ assertThrows(OMException.class, () -> fs.isFileClosed(source));
+ stream.write(1);
+ stream.hsync();
+ assertFalse(fs.isFileClosed(source));
+ assertTrue(fs.recoverLease(source));
+ assertTrue(fs.isFileClosed(source));
+ }
}
diff --git
a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
index a64283fb1c..f38873a9e0 100644
--- a/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
+++ b/hadoop-ozone/interface-client/src/main/proto/OmClientProtocol.proto
@@ -139,6 +139,14 @@ enum Type {
RefetchSecretKey = 121;
ListSnapshotDiffJobs = 122;
CancelSnapshotDiff = 123;
+ SetSafeMode = 124;
+}
+
+enum SafeMode {
+ ENTER = 1;
+ LEAVE = 2;
+ FORCE_EXIT = 3;
+ GET = 4;
}
message OMRequest {
@@ -259,9 +267,9 @@ message OMRequest {
optional RecoverLeaseRequest RecoverLeaseRequest =
119;
optional SetTimesRequest SetTimesRequest =
120;
optional RefetchSecretKeyRequest RefetchSecretKeyRequest =
121;
-
optional ListSnapshotDiffJobRequest ListSnapshotDiffJobRequest =
122;
optional CancelSnapshotDiffRequest CancelSnapshotDiffRequest = 123;
+ optional SetSafeModeRequest SetSafeModeRequest =
124;
}
message OMResponse {
@@ -374,9 +382,9 @@ message OMResponse {
optional RecoverLeaseResponse RecoverLeaseResponse =
119;
optional SetTimesResponse SetTimesResponse =
120;
optional RefetchSecretKeyResponse RefetchSecretKeyResponse =
121;
-
optional ListSnapshotDiffJobResponse ListSnapshotDiffJobResponse =
122;
optional CancelSnapshotDiffResponse cancelSnapshotDiffResponse = 123;
+ optional SetSafeModeResponse SetSafeModeResponse =
124;
}
enum Status {
@@ -1954,6 +1962,14 @@ message SetTimesRequest {
message SetTimesResponse {
}
+message SetSafeModeRequest {
+ required SafeMode safeMode = 1;
+}
+
+message SetSafeModeResponse {
+ optional bool response = 1;
+}
+
/**
The OM service that takes care of Ozone namespace.
*/
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
index 95eb39caae..ccbd673414 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/OzoneManager.java
@@ -59,6 +59,7 @@ import org.apache.hadoop.fs.CommonConfigurationKeys;
import org.apache.hadoop.fs.CommonConfigurationKeysPublic;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.hdds.HddsConfigKeys;
import org.apache.hadoop.hdds.HddsUtils;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
@@ -288,6 +289,7 @@ import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_SERVER_DEFAULT_REPLI
import static
org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_SERVER_DEFAULT_REPLICATION_TYPE_KEY;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.DETECTED_LOOP_IN_BUCKET_LINKS;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.FEATURE_NOT_ENABLED;
+import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INTERNAL_ERROR;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_AUTH_METHOD;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_REQUEST;
import static
org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.PERMISSION_DENIED;
@@ -4469,6 +4471,25 @@ public final class OzoneManager extends
ServiceRuntimeInfoImpl
throws IOException {
}
+ @Override
+ public boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException {
+ switch (action) {
+ case ENTER:
+ throw new OMException("Enter safe mode is unsupported",
+ INTERNAL_ERROR);
+ case FORCE_EXIT:
+ return getScmClient().getContainerClient().forceExitSafeMode();
+ case GET:
+ return getScmClient().getContainerClient().inSafeMode();
+ //case LEAVE:
+ // TODO: support LEAVE in the future.
+ default:
+ throw new OMException("Unsupported safe mode action " + action,
+ INTERNAL_ERROR);
+ }
+ }
+
/**
* Write down Layout version of a finalized feature to DB on finalization.
* @param lvm OMLayoutVersionManager
diff --git
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
index 7ccdc4fd59..e6023d23a1 100644
---
a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
+++
b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/protocolPB/OzoneManagerRequestHandler.java
@@ -30,6 +30,7 @@ import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.hdds.client.ECReplicationConfig;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
import
org.apache.hadoop.hdds.protocol.proto.HddsProtos.TransferLeadershipRequestProto;
@@ -115,6 +116,8 @@ import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RangerB
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RepeatedKeyInfo;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListRequest;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListResponse;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetSafeModeRequest;
+import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SetSafeModeResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeContextResponse;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status;
import
org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SnapshotDiffRequest;
@@ -333,6 +336,10 @@ public class OzoneManagerRequestHandler implements
RequestHandler {
case RefetchSecretKey:
responseBuilder.setRefetchSecretKeyResponse(refetchSecretKey());
break;
+ case SetSafeMode:
+ SetSafeModeResponse setSafeModeResponse =
+ setSafeMode(request.getSetSafeModeRequest());
+ responseBuilder.setSetSafeModeResponse(setSafeModeResponse);
default:
responseBuilder.setSuccess(false);
responseBuilder.setMessage("Unrecognized Command Type: " + cmdType);
@@ -1356,4 +1363,30 @@ public class OzoneManagerRequestHandler implements
RequestHandler {
impl.transferLeadership(newLeaderId);
return TransferLeadershipResponseProto.getDefaultInstance();
}
+
+ private SetSafeModeResponse setSafeMode(
+ SetSafeModeRequest req) throws IOException {
+ OzoneManagerProtocolProtos.SafeMode safeMode = req.getSafeMode();
+ boolean response = impl.setSafeMode(toSafeModeAction(safeMode), false);
+ return SetSafeModeResponse.newBuilder()
+ .setResponse(response)
+ .build();
+ }
+
+ private SafeModeAction toSafeModeAction(
+ OzoneManagerProtocolProtos.SafeMode safeMode) {
+ switch (safeMode) {
+ case ENTER:
+ return SafeModeAction.ENTER;
+ case LEAVE:
+ return SafeModeAction.LEAVE;
+ case FORCE_EXIT:
+ return SafeModeAction.FORCE_EXIT;
+ case GET:
+ return SafeModeAction.GET;
+ default:
+ throw new IllegalArgumentException("Unexpected safe mode action " +
+ safeMode);
+ }
+ }
}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/LeaseRecoverable.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/LeaseRecoverable.java
new file mode 100644
index 0000000000..03d93bef56
--- /dev/null
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/LeaseRecoverable.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.fs;
+
+import java.io.IOException;
+
+/**
+ * FIXME: Hack: This is copied from Hadoop 3.3.6. Remove this interface once
+ * we drop Hadoop 3.1, 3.2 support.
+ * Whether the given Path of the FileSystem has the capability to perform lease
+ * recovery.
+ */
+public interface LeaseRecoverable {
+
+ /**
+ * Start the lease recovery of a file.
+ *
+ * @param file path to a file.
+ * @return true if the file is already closed, and it does not require lease
+ * recovery.
+ * @throws IOException if an error occurs during lease recovery.
+ * @throws UnsupportedOperationException if lease recovery is not supported
+ * by this filesystem.
+ */
+ boolean recoverLease(Path file) throws IOException;
+
+ /**
+ * Get the close status of a file.
+ * @param file The string representation of the path to the file
+ * @return return true if file is closed
+ * @throws IOException If an I/O error occurred
+ * @throws UnsupportedOperationException if isFileClosed is not supported by
+ * this filesystem.
+ */
+ boolean isFileClosed(Path file) throws IOException;
+}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/SafeMode.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/SafeMode.java
new file mode 100644
index 0000000000..e9fb827ded
--- /dev/null
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/SafeMode.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.hadoop.fs;
+
+import java.io.IOException;
+
+/**
+ * FIXME: Hack: This is copied from Hadoop 3.3.6. Remove this interface once
+ * we drop Hadoop 3.1, 3.2 support.
+ * Whether the given filesystem is in any status of safe mode.
+ */
+public interface SafeMode {
+
+ /**
+ * Enter, leave, or get safe mode.
+ *
+ * @param action One of {@link SafeModeAction} LEAVE, ENTER, GET, FORCE_EXIT.
+ * @throws IOException if set safe mode fails to proceed.
+ * @return true if the action is successfully accepted, otherwise false means
+ * rejected.
+ */
+ default boolean setSafeMode(SafeModeAction action) throws IOException {
+ return setSafeMode(action, false);
+ }
+
+ /**
+ * Enter, leave, or get safe mode.
+ *
+ * @param action One of {@link SafeModeAction} LEAVE, ENTER, GET,
+ * FORCE_EXIT.
+ * @param isChecked If true check only for Active metadata node / NameNode's
+ * status,
+ * else check first metadata node / NameNode's status.
+ * @throws IOException if set safe mode fails to proceed.
+ * @return true if the action is successfully accepted, otherwise false means
+ * rejected.
+ */
+ boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException;
+
+}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/SafeModeAction.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/SafeModeAction.java
new file mode 100644
index 0000000000..20e7cb9f19
--- /dev/null
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/SafeModeAction.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.fs;
+
+/**
+ * FIXME: Hack: This is copied from Hadoop 3.3.6. Remove this interface once
+ * we drop Hadoop 3.1, 3.2 support.
+ * An identical copy from org.apache.hadoop.hdfs.protocol.HdfsConstants
+ * .SafeModeAction, that helps
+ * the other file system implementation to define {@link SafeMode}.
+ */
+public enum SafeModeAction {
+ /**
+ * Starting entering into safe mode.
+ */
+ ENTER,
+ /**
+ * Gracefully exit from safe mode.
+ */
+ LEAVE,
+ /**
+ * Force Exit from safe mode.
+ */
+ FORCE_EXIT,
+ /**
+ * Get the status of the safe mode.
+ */
+ GET;
+}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java
index 6090722306..443ba17d59 100644
---
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneClientAdapterImpl.java
@@ -36,6 +36,7 @@ import org.apache.hadoop.fs.FileAlreadyExistsException;
import org.apache.hadoop.fs.FileChecksum;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathIsNotEmptyDirectoryException;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.client.ReplicationConfig;
import org.apache.hadoop.hdds.client.ReplicationFactor;
@@ -716,9 +717,40 @@ public class BasicOzoneClientAdapterImpl implements
OzoneClientAdapter {
return snapshotDiffResponse.getSnapshotDiffReport();
}
+ @Override
+ public boolean recoverLease(final String pathStr) throws IOException {
+ incrementCounter(Statistic.INVOCATION_RECOVER_LEASE, 1);
+
+ return ozoneClient.getProxy().getOzoneManagerClient().recoverLease(
+ volume.getName(), bucket.getName(), pathStr);
+ }
+
@Override
public void setTimes(String key, long mtime, long atime) throws IOException {
incrementCounter(Statistic.INVOCATION_SET_TIMES, 1);
bucket.setTimes(key, mtime, atime);
}
+
+ @Override
+ public boolean isFileClosed(String pathStr) throws IOException {
+ incrementCounter(Statistic.INVOCATION_IS_FILE_CLOSED, 1);
+ OFSPath ofsPath = new OFSPath(pathStr, config);
+ if (!ofsPath.isKey()) {
+ throw new IOException("not a file");
+ }
+ OzoneFileStatus status = bucket.getFileStatus(pathStr);
+ if (!status.isFile()) {
+ throw new IOException("not a file");
+ }
+ return !status.getKeyInfo().isHsync();
+ }
+
+ @Override
+ public boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException {
+ incrementCounter(Statistic.INVOCATION_SET_SAFE_MODE, 1);
+
+ return ozoneClient.getProxy().getOzoneManagerClient().setSafeMode(
+ action, isChecked);
+ }
}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneFileSystem.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneFileSystem.java
index 9b654062da..f095d42713 100644
---
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneFileSystem.java
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicOzoneFileSystem.java
@@ -35,6 +35,7 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathFilter;
import org.apache.hadoop.fs.PathIsNotEmptyDirectoryException;
import org.apache.hadoop.fs.RemoteIterator;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.annotation.InterfaceStability;
@@ -1266,4 +1267,16 @@ public class BasicOzoneFileSystem extends FileSystem {
}
return new LocatedFileStatus(fileStatus, blockLocations);
}
+
+ protected boolean setSafeModeUtil(SafeModeAction action,
+ boolean isChecked)
+ throws IOException {
+ if (action == SafeModeAction.GET) {
+ statistics.incrementReadOps(1);
+ } else {
+ statistics.incrementWriteOps(1);
+ }
+ LOG.trace("setSafeMode() action:{}", action);
+ return getAdapter().setSafeMode(action, isChecked);
+ }
}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneClientAdapterImpl.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneClientAdapterImpl.java
index 3bdde5333d..6c6be73680 100644
---
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneClientAdapterImpl.java
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneClientAdapterImpl.java
@@ -41,6 +41,7 @@ import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathIsNotEmptyDirectoryException;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.client.ReplicationConfig;
@@ -1370,8 +1371,31 @@ public class BasicRootedOzoneClientAdapterImpl
return snapshotDiffResponse.getSnapshotDiffReport();
}
- public boolean recoverLease(final Path f) throws IOException {
- OFSPath ofsPath = new OFSPath(f, config);
+ @Override
+ public boolean isFileClosed(String pathStr) throws IOException {
+ incrementCounter(Statistic.INVOCATION_IS_FILE_CLOSED, 1);
+ OFSPath ofsPath = new OFSPath(pathStr, config);
+ String key = ofsPath.getKeyName();
+ if (ofsPath.isRoot() || ofsPath.isVolume()) {
+ throw new IOException("not a file");
+ } else {
+ OzoneBucket bucket = getBucket(ofsPath, false);
+ if (ofsPath.isSnapshotPath()) {
+ throw new IOException("file is in a snapshot.");
+ } else {
+ OzoneFileStatus status = bucket.getFileStatus(key);
+ if (!status.isFile()) {
+ throw new IOException("not a file");
+ }
+ return !status.getKeyInfo().isHsync();
+ }
+ }
+ }
+
+ @Override
+ public boolean recoverLease(final String pathStr) throws IOException {
+ incrementCounter(Statistic.INVOCATION_RECOVER_LEASE, 1);
+ OFSPath ofsPath = new OFSPath(pathStr, config);
OzoneVolume volume = objectStore.getVolume(ofsPath.getVolumeName());
OzoneBucket bucket = getBucket(ofsPath, false);
@@ -1379,6 +1403,7 @@ public class BasicRootedOzoneClientAdapterImpl
volume.getName(), bucket.getName(), ofsPath.getKeyName());
}
+ @Override
public void setTimes(String key, long mtime, long atime) throws IOException {
incrementCounter(Statistic.INVOCATION_SET_TIMES, 1);
OFSPath ofsPath = new OFSPath(key, config);
@@ -1386,4 +1411,13 @@ public class BasicRootedOzoneClientAdapterImpl
OzoneBucket bucket = getBucket(ofsPath, false);
bucket.setTimes(ofsPath.getKeyName(), mtime, atime);
}
+
+ @Override
+ public boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException {
+ incrementCounter(Statistic.INVOCATION_SET_SAFE_MODE, 1);
+
+ return ozoneClient.getProxy().getOzoneManagerClient().setSafeMode(
+ action, isChecked);
+ }
}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneFileSystem.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneFileSystem.java
index 2639a8f05d..e560b47663 100644
---
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneFileSystem.java
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/BasicRootedOzoneFileSystem.java
@@ -33,6 +33,7 @@ import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathFilter;
import org.apache.hadoop.fs.PathIsNotEmptyDirectoryException;
import org.apache.hadoop.fs.RemoteIterator;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.fs.permission.FsPermission;
import org.apache.hadoop.fs.ContentSummary;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
@@ -1543,18 +1544,6 @@ public class BasicRootedOzoneFileSystem extends
FileSystem {
return adapter.getSnapshotDiffReport(snapshotDir, fromSnapshot,
toSnapshot);
}
-
- /**
- * Start the lease recovery of a file.
- *
- * @param f a file
- * @return true if the file is already closed
- * @throws IOException if an error occurs
- */
- public boolean recoverLease(final Path f) throws IOException {
- return adapterImpl.recoverLease(f);
- }
-
@Override
public void setTimes(Path f, long mtime, long atime) throws IOException {
incrementCounter(Statistic.INVOCATION_SET_TIMES, 1);
@@ -1569,4 +1558,15 @@ public class BasicRootedOzoneFileSystem extends
FileSystem {
adapter.setTimes(key, mtime, atime);
}
+ protected boolean setSafeModeUtil(SafeModeAction action,
+ boolean isChecked)
+ throws IOException {
+ if (action == SafeModeAction.GET) {
+ statistics.incrementReadOps(1);
+ } else {
+ statistics.incrementWriteOps(1);
+ }
+ LOG.trace("setSafeMode() action:{}", action);
+ return getAdapter().setSafeMode(action, isChecked);
+ }
}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientAdapter.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientAdapter.java
index 80cc50b9b9..c48f1a6366 100644
---
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientAdapter.java
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientAdapter.java
@@ -26,6 +26,7 @@ import java.util.List;
import org.apache.hadoop.crypto.key.KeyProvider;
import org.apache.hadoop.fs.FileChecksum;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.hdfs.protocol.SnapshotDiffReport;
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
import org.apache.hadoop.security.token.Token;
@@ -94,5 +95,12 @@ public interface OzoneClientAdapter {
String fromSnapshot, String toSnapshot)
throws IOException, InterruptedException;
+ boolean recoverLease(String pathStr) throws IOException;
+
void setTimes(String key, long mtime, long atime) throws IOException;
+
+ boolean isFileClosed(String pathStr) throws IOException;
+
+ boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException;
}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientUtils.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientUtils.java
index 2c6ce21aa0..cb62811176 100644
---
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientUtils.java
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/OzoneClientUtils.java
@@ -267,5 +267,4 @@ public final class OzoneClientUtils {
}
return limitVal;
}
-
}
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/Statistic.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/Statistic.java
index 09b9cdd777..aae71e9c4c 100644
---
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/Statistic.java
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/ozone/Statistic.java
@@ -74,7 +74,13 @@ public enum Statistic {
INVOCATION_RENAME(CommonStatisticNames.OP_RENAME,
"Calls of rename()"),
INVOCATION_SET_TIMES(CommonStatisticNames.OP_SET_TIMES,
- "Calls of setTimes()");
+ "Calls of setTimes()"),
+ INVOCATION_IS_FILE_CLOSED("op_is_file_closed",
+ "Calls of isFileClosed()"),
+ INVOCATION_RECOVER_LEASE("op_recover_lease",
+ "Calls of recoverLease()"),
+ INVOCATION_SET_SAFE_MODE("op_set_safe_mode",
+ "Calls of setSafeMode()");
private static final Map<String, Statistic> SYMBOL_MAP =
new HashMap<>(Statistic.values().length);
diff --git
a/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/package-info.java
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/package-info.java
new file mode 100644
index 0000000000..7c6d4c2c50
--- /dev/null
+++
b/hadoop-ozone/ozonefs-common/src/main/java/org/apache/hadoop/fs/package-info.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * Interface definitions borrowed from Hadoop 3.3.6.
+ * FIXME: Hack: This is copied from Hadoop 3.3.6. Remove this interface once
+ * we drop Hadoop 3.1, 3.2 support.
+ */
[email protected]
[email protected]
+package org.apache.hadoop.fs;
+
+import org.apache.hadoop.hdds.annotation.InterfaceAudience;
+import org.apache.hadoop.hdds.annotation.InterfaceStability;
diff --git
a/hadoop-ozone/ozonefs-hadoop3/src/main/java/org/apache/hadoop/fs/ozone/OzoneFileSystem.java
b/hadoop-ozone/ozonefs-hadoop3/src/main/java/org/apache/hadoop/fs/ozone/OzoneFileSystem.java
index 8fa46d7a53..203e7ed373 100644
---
a/hadoop-ozone/ozonefs-hadoop3/src/main/java/org/apache/hadoop/fs/ozone/OzoneFileSystem.java
+++
b/hadoop-ozone/ozonefs-hadoop3/src/main/java/org/apache/hadoop/fs/ozone/OzoneFileSystem.java
@@ -25,7 +25,10 @@ import java.net.URI;
import org.apache.hadoop.crypto.key.KeyProvider;
import org.apache.hadoop.crypto.key.KeyProviderTokenIssuer;
import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.LeaseRecoverable;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.SafeMode;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.fs.StorageStatistics;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.annotation.InterfaceStability;
@@ -43,7 +46,7 @@ import org.apache.hadoop.security.token.DelegationTokenIssuer;
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class OzoneFileSystem extends BasicOzoneFileSystem
- implements KeyProviderTokenIssuer {
+ implements KeyProviderTokenIssuer, LeaseRecoverable, SafeMode {
private OzoneFSStorageStatistics storageStatistics;
@@ -120,4 +123,26 @@ public class OzoneFileSystem extends BasicOzoneFileSystem
}
return super.hasPathCapability(p, capability);
}
+
+ @Override
+ public boolean recoverLease(Path f) throws IOException {
+ LOG.trace("recoverLease() path:{}", f);
+ Path qualifiedPath = makeQualified(f);
+ String key = pathToKey(qualifiedPath);
+ return getAdapter().recoverLease(key);
+ }
+
+ @Override
+ public boolean isFileClosed(Path f) throws IOException {
+ LOG.trace("isFileClosed() path:{}", f);
+ Path qualifiedPath = makeQualified(f);
+ String key = pathToKey(qualifiedPath);
+ return getAdapter().isFileClosed(key);
+ }
+
+ @Override
+ public boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException {
+ return setSafeModeUtil(action, isChecked);
+ }
}
diff --git
a/hadoop-ozone/ozonefs-hadoop3/src/main/java/org/apache/hadoop/fs/ozone/RootedOzoneFileSystem.java
b/hadoop-ozone/ozonefs-hadoop3/src/main/java/org/apache/hadoop/fs/ozone/RootedOzoneFileSystem.java
index 8243e04f9c..9b1596c05b 100644
---
a/hadoop-ozone/ozonefs-hadoop3/src/main/java/org/apache/hadoop/fs/ozone/RootedOzoneFileSystem.java
+++
b/hadoop-ozone/ozonefs-hadoop3/src/main/java/org/apache/hadoop/fs/ozone/RootedOzoneFileSystem.java
@@ -18,7 +18,10 @@
package org.apache.hadoop.fs.ozone;
+import org.apache.hadoop.fs.LeaseRecoverable;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.SafeMode;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.annotation.InterfaceStability;
import org.apache.hadoop.hdds.conf.ConfigurationSource;
@@ -43,7 +46,7 @@ import java.net.URI;
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class RootedOzoneFileSystem extends BasicRootedOzoneFileSystem
- implements KeyProviderTokenIssuer {
+ implements KeyProviderTokenIssuer, LeaseRecoverable, SafeMode {
private OzoneFSStorageStatistics storageStatistics;
@@ -118,4 +121,37 @@ public class RootedOzoneFileSystem extends
BasicRootedOzoneFileSystem
}
return super.hasPathCapability(p, capability);
}
+
+ /**
+ * Start the lease recovery of a file.
+ *
+ * @param f a file
+ * @return true if the file is already closed
+ * @throws IOException if an error occurs
+ */
+ @Override
+ public boolean recoverLease(final Path f) throws IOException {
+ incrementCounter(Statistic.INVOCATION_RECOVER_LEASE, 1);
+ statistics.incrementWriteOps(1);
+ LOG.trace("recoverLease() path:{}", f);
+ Path qualifiedPath = makeQualified(f);
+ String key = pathToKey(qualifiedPath);
+ return getAdapter().recoverLease(key);
+ }
+
+ @Override
+ public boolean isFileClosed(Path f) throws IOException {
+ incrementCounter(Statistic.INVOCATION_IS_FILE_CLOSED, 1);
+ statistics.incrementReadOps(1);
+ LOG.trace("isFileClosed() path:{}", f);
+ Path qualifiedPath = makeQualified(f);
+ String key = pathToKey(qualifiedPath);
+ return getAdapter().isFileClosed(key);
+ }
+
+ @Override
+ public boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException {
+ return setSafeModeUtil(action, isChecked);
+ }
}
diff --git
a/hadoop-ozone/ozonefs/src/main/java/org/apache/hadoop/fs/ozone/OzoneFileSystem.java
b/hadoop-ozone/ozonefs/src/main/java/org/apache/hadoop/fs/ozone/OzoneFileSystem.java
index 8fa46d7a53..71f01e4414 100644
---
a/hadoop-ozone/ozonefs/src/main/java/org/apache/hadoop/fs/ozone/OzoneFileSystem.java
+++
b/hadoop-ozone/ozonefs/src/main/java/org/apache/hadoop/fs/ozone/OzoneFileSystem.java
@@ -25,7 +25,10 @@ import java.net.URI;
import org.apache.hadoop.crypto.key.KeyProvider;
import org.apache.hadoop.crypto.key.KeyProviderTokenIssuer;
import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.LeaseRecoverable;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.SafeMode;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.fs.StorageStatistics;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.annotation.InterfaceStability;
@@ -43,7 +46,7 @@ import org.apache.hadoop.security.token.DelegationTokenIssuer;
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class OzoneFileSystem extends BasicOzoneFileSystem
- implements KeyProviderTokenIssuer {
+ implements KeyProviderTokenIssuer, LeaseRecoverable, SafeMode {
private OzoneFSStorageStatistics storageStatistics;
@@ -120,4 +123,26 @@ public class OzoneFileSystem extends BasicOzoneFileSystem
}
return super.hasPathCapability(p, capability);
}
+
+ @Override
+ public boolean recoverLease(Path f) throws IOException {
+ LOG.trace("isFileClosed() path:{}", f);
+ Path qualifiedPath = makeQualified(f);
+ String key = pathToKey(qualifiedPath);
+ return getAdapter().recoverLease(key);
+ }
+
+ @Override
+ public boolean isFileClosed(Path f) throws IOException {
+ LOG.trace("isFileClosed() path:{}", f);
+ Path qualifiedPath = makeQualified(f);
+ String key = pathToKey(qualifiedPath);
+ return getAdapter().isFileClosed(key);
+ }
+
+ @Override
+ public boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException {
+ return setSafeModeUtil(action, isChecked);
+ }
}
diff --git
a/hadoop-ozone/ozonefs/src/main/java/org/apache/hadoop/fs/ozone/RootedOzoneFileSystem.java
b/hadoop-ozone/ozonefs/src/main/java/org/apache/hadoop/fs/ozone/RootedOzoneFileSystem.java
index 8808e28e88..7561e20a87 100644
---
a/hadoop-ozone/ozonefs/src/main/java/org/apache/hadoop/fs/ozone/RootedOzoneFileSystem.java
+++
b/hadoop-ozone/ozonefs/src/main/java/org/apache/hadoop/fs/ozone/RootedOzoneFileSystem.java
@@ -18,7 +18,10 @@
package org.apache.hadoop.fs.ozone;
+import org.apache.hadoop.fs.LeaseRecoverable;
import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.fs.SafeMode;
+import org.apache.hadoop.fs.SafeModeAction;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.annotation.InterfaceStability;
import org.apache.hadoop.hdds.conf.ConfigurationSource;
@@ -43,7 +46,7 @@ import java.net.URI;
@InterfaceAudience.Private
@InterfaceStability.Evolving
public class RootedOzoneFileSystem extends BasicRootedOzoneFileSystem
- implements KeyProviderTokenIssuer {
+ implements KeyProviderTokenIssuer, LeaseRecoverable, SafeMode {
private OzoneFSStorageStatistics storageStatistics;
@@ -118,4 +121,28 @@ public class RootedOzoneFileSystem extends
BasicRootedOzoneFileSystem
}
return super.hasPathCapability(p, capability);
}
+
+ @Override
+ public boolean recoverLease(final Path f) throws IOException {
+ statistics.incrementWriteOps(1);
+ LOG.trace("recoverLease() path:{}", f);
+ Path qualifiedPath = makeQualified(f);
+ String key = pathToKey(qualifiedPath);
+ return getAdapter().recoverLease(key);
+ }
+
+ @Override
+ public boolean isFileClosed(Path f) throws IOException {
+ statistics.incrementWriteOps(1);
+ LOG.trace("isFileClosed() path:{}", f);
+ Path qualifiedPath = makeQualified(f);
+ String key = pathToKey(qualifiedPath);
+ return getAdapter().isFileClosed(key);
+ }
+
+ @Override
+ public boolean setSafeMode(SafeModeAction action, boolean isChecked)
+ throws IOException {
+ return setSafeModeUtil(action, isChecked);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]