|
@@ -124,6 +124,7 @@ import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.fs.BatchedRemoteIterator.BatchedListEntries;
|
|
|
import org.apache.hadoop.fs.ContentSummary;
|
|
|
import org.apache.hadoop.fs.CreateFlag;
|
|
|
+import org.apache.hadoop.fs.DirectoryListingStartAfterNotFoundException;
|
|
|
import org.apache.hadoop.fs.FileAlreadyExistsException;
|
|
|
import org.apache.hadoop.fs.FileStatus;
|
|
|
import org.apache.hadoop.fs.FsServerDefaults;
|
|
@@ -168,7 +169,14 @@ import org.apache.hadoop.hdfs.security.token.block.BlockTokenSecretManager;
|
|
|
import org.apache.hadoop.hdfs.security.token.block.BlockTokenSecretManager.AccessMode;
|
|
|
import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenIdentifier;
|
|
|
import org.apache.hadoop.hdfs.security.token.delegation.DelegationTokenSecretManager;
|
|
|
-import org.apache.hadoop.hdfs.server.blockmanagement.*;
|
|
|
+import org.apache.hadoop.hdfs.server.blockmanagement.BlockCollection;
|
|
|
+import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo;
|
|
|
+import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfoUnderConstruction;
|
|
|
+import org.apache.hadoop.hdfs.server.blockmanagement.BlockManager;
|
|
|
+import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor;
|
|
|
+import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeManager;
|
|
|
+import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeStatistics;
|
|
|
+import org.apache.hadoop.hdfs.server.blockmanagement.OutOfV1GenerationStampsException;
|
|
|
import org.apache.hadoop.hdfs.server.common.GenerationStamp;
|
|
|
import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.BlockUCState;
|
|
|
import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.NamenodeRole;
|
|
@@ -181,12 +189,6 @@ import org.apache.hadoop.hdfs.server.namenode.INode.BlocksMapUpdateInfo;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.JournalSet.JournalAndStream;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.NameNode.OperationCategory;
|
|
|
-import org.apache.hadoop.hdfs.server.namenode.startupprogress.Phase;
|
|
|
-import org.apache.hadoop.hdfs.server.namenode.startupprogress.StartupProgress;
|
|
|
-import org.apache.hadoop.hdfs.server.namenode.startupprogress.StartupProgress.Counter;
|
|
|
-import org.apache.hadoop.hdfs.server.namenode.startupprogress.Status;
|
|
|
-import org.apache.hadoop.hdfs.server.namenode.startupprogress.Step;
|
|
|
-import org.apache.hadoop.hdfs.server.namenode.startupprogress.StepType;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.ha.HAContext;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.ha.HAState;
|
|
@@ -198,6 +200,12 @@ import org.apache.hadoop.hdfs.server.namenode.snapshot.INodeDirectorySnapshottab
|
|
|
import org.apache.hadoop.hdfs.server.namenode.snapshot.INodeFileWithSnapshot;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.snapshot.Snapshot;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.snapshot.SnapshotManager;
|
|
|
+import org.apache.hadoop.hdfs.server.namenode.startupprogress.Phase;
|
|
|
+import org.apache.hadoop.hdfs.server.namenode.startupprogress.StartupProgress;
|
|
|
+import org.apache.hadoop.hdfs.server.namenode.startupprogress.StartupProgress.Counter;
|
|
|
+import org.apache.hadoop.hdfs.server.namenode.startupprogress.Status;
|
|
|
+import org.apache.hadoop.hdfs.server.namenode.startupprogress.Step;
|
|
|
+import org.apache.hadoop.hdfs.server.namenode.startupprogress.StepType;
|
|
|
import org.apache.hadoop.hdfs.server.namenode.web.resources.NamenodeWebHdfsMethods;
|
|
|
import org.apache.hadoop.hdfs.server.protocol.DatanodeCommand;
|
|
|
import org.apache.hadoop.hdfs.server.protocol.DatanodeRegistration;
|
|
@@ -210,6 +218,7 @@ import org.apache.hadoop.hdfs.server.protocol.ReceivedDeletedBlockInfo;
|
|
|
import org.apache.hadoop.hdfs.util.ChunkedArrayList;
|
|
|
import org.apache.hadoop.io.IOUtils;
|
|
|
import org.apache.hadoop.io.Text;
|
|
|
+import org.apache.hadoop.ipc.RetriableException;
|
|
|
import org.apache.hadoop.ipc.RetryCache;
|
|
|
import org.apache.hadoop.ipc.RetryCache.CacheEntry;
|
|
|
import org.apache.hadoop.ipc.RetryCache.CacheEntryWithPayload;
|
|
@@ -238,6 +247,7 @@ import org.mortbay.util.ajax.JSON;
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
|
import com.google.common.base.Charsets;
|
|
|
import com.google.common.base.Preconditions;
|
|
|
+import com.google.common.collect.ImmutableMap;
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
|
/**
|
|
@@ -440,7 +450,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
private final long accessTimePrecision;
|
|
|
|
|
|
/** Lock to protect FSNamesystem. */
|
|
|
- private ReentrantReadWriteLock fsLock = new ReentrantReadWriteLock(true);
|
|
|
+ private ReentrantReadWriteLock fsLock;
|
|
|
|
|
|
/**
|
|
|
* Used when this NN is in standby state to read from the shared edit log.
|
|
@@ -459,6 +469,11 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
private HAContext haContext;
|
|
|
|
|
|
private final boolean haEnabled;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Whether the namenode is in the middle of starting the active service
|
|
|
+ */
|
|
|
+ private volatile boolean startingActiveService = false;
|
|
|
|
|
|
private INodeId inodeId;
|
|
|
|
|
@@ -615,6 +630,9 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
*/
|
|
|
FSNamesystem(Configuration conf, FSImage fsImage, boolean ignoreRetryCache)
|
|
|
throws IOException {
|
|
|
+ boolean fair = conf.getBoolean("dfs.namenode.fslock.fair", true);
|
|
|
+ LOG.info("fsLock is fair:" + fair);
|
|
|
+ fsLock = new ReentrantReadWriteLock(fair);
|
|
|
try {
|
|
|
resourceRecheckInterval = conf.getLong(
|
|
|
DFS_NAMENODE_RESOURCE_CHECK_INTERVAL_KEY,
|
|
@@ -911,6 +929,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
* @throws IOException
|
|
|
*/
|
|
|
void startActiveServices() throws IOException {
|
|
|
+ startingActiveService = true;
|
|
|
LOG.info("Starting services required for active state");
|
|
|
writeLock();
|
|
|
try {
|
|
@@ -967,8 +986,19 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
blockManager.getDatanodeManager().setSendCachingCommands(true);
|
|
|
} finally {
|
|
|
writeUnlock();
|
|
|
+ startingActiveService = false;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @return Whether the namenode is transitioning to active state and is in the
|
|
|
+ * middle of the {@link #startActiveServices()}
|
|
|
+ */
|
|
|
+ public boolean inTransitionToActive() {
|
|
|
+ return haEnabled && haContext != null
|
|
|
+ && haContext.getState().getServiceState() == HAServiceState.ACTIVE
|
|
|
+ && startingActiveService;
|
|
|
+ }
|
|
|
|
|
|
private boolean shouldUseDelegationTokens() {
|
|
|
return UserGroupInformation.isSecurityEnabled() ||
|
|
@@ -1063,6 +1093,26 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @throws RetriableException
|
|
|
+ * If 1) The NameNode is in SafeMode, 2) HA is enabled, and 3)
|
|
|
+ * NameNode is in active state
|
|
|
+ * @throws SafeModeException
|
|
|
+ * Otherwise if NameNode is in SafeMode.
|
|
|
+ */
|
|
|
+ private void checkNameNodeSafeMode(String errorMsg)
|
|
|
+ throws RetriableException, SafeModeException {
|
|
|
+ if (isInSafeMode()) {
|
|
|
+ SafeModeException se = new SafeModeException(errorMsg, safeMode);
|
|
|
+ if (haEnabled && haContext != null
|
|
|
+ && haContext.getState().getServiceState() == HAServiceState.ACTIVE) {
|
|
|
+ throw new RetriableException(se);
|
|
|
+ } else {
|
|
|
+ throw se;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
public static Collection<URI> getNamespaceDirs(Configuration conf) {
|
|
|
return getStorageDirs(conf, DFS_NAMENODE_NAME_DIR_KEY);
|
|
|
}
|
|
@@ -1364,9 +1414,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot set permission for " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot set permission for " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
checkOwner(pc, src);
|
|
|
dir.setPermission(src, permission);
|
|
@@ -1403,9 +1451,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot set owner for " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot set owner for " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
checkOwner(pc, src);
|
|
|
if (!pc.isSuperUser()) {
|
|
@@ -1485,8 +1531,14 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
for (LocatedBlock b : ret.getLocatedBlocks()) {
|
|
|
// if safemode & no block locations yet then throw safemodeException
|
|
|
if ((b.getLocations() == null) || (b.getLocations().length == 0)) {
|
|
|
- throw new SafeModeException("Zero blocklocations for " + src,
|
|
|
- safeMode);
|
|
|
+ SafeModeException se = new SafeModeException(
|
|
|
+ "Zero blocklocations for " + src, safeMode);
|
|
|
+ if (haEnabled && haContext != null &&
|
|
|
+ haContext.getState().getServiceState() == HAServiceState.ACTIVE) {
|
|
|
+ throw new RetriableException(se);
|
|
|
+ } else {
|
|
|
+ throw se;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1633,9 +1685,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot concat " + target, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot concat " + target);
|
|
|
concatInternal(pc, target, srcs, logRetryCache);
|
|
|
resultingStat = getAuditFileInfo(target, false);
|
|
|
} finally {
|
|
@@ -1783,9 +1833,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot set times " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot set times " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
|
|
|
// Write access is required to set access and modification times
|
|
@@ -1812,16 +1860,16 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
void createSymlink(String target, String link,
|
|
|
PermissionStatus dirPerms, boolean createParent)
|
|
|
throws IOException, UnresolvedLinkException {
|
|
|
- CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
- if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
- return; // Return previous response
|
|
|
- }
|
|
|
if (!DFSUtil.isValidName(link)) {
|
|
|
throw new InvalidPathException("Invalid link name: " + link);
|
|
|
}
|
|
|
if (FSDirectory.isReservedName(target)) {
|
|
|
throw new InvalidPathException("Invalid target name: " + target);
|
|
|
}
|
|
|
+ CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
+ if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
+ return; // Return previous response
|
|
|
+ }
|
|
|
boolean success = false;
|
|
|
try {
|
|
|
createSymlinkInt(target, link, dirPerms, createParent, cacheEntry != null);
|
|
@@ -1848,9 +1896,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot create symlink " + link, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot create symlink " + link);
|
|
|
link = FSDirectory.resolvePath(link, pathComponents, dir);
|
|
|
if (!createParent) {
|
|
|
verifyParentDir(link);
|
|
@@ -1908,9 +1954,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot set replication for " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot set replication for " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
if (isPermissionEnabled) {
|
|
|
checkPathAccess(pc, src, FsAction.WRITE);
|
|
@@ -2040,9 +2084,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot create file" + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot create file" + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
startFileInternal(pc, src, permissions, holder, clientMachine, create,
|
|
|
overwrite, createParent, replication, blockSize, logRetryCache);
|
|
@@ -2261,10 +2303,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException(
|
|
|
- "Cannot recover the lease of " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot recover the lease of " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
final INodeFile inode = INodeFile.valueOf(dir.getINode(src), src);
|
|
|
if (!inode.isUnderConstruction()) {
|
|
@@ -2415,9 +2454,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot append to file" + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot append to file" + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
lb = appendFileInternal(pc, src, holder, clientMachine, logRetryCache);
|
|
|
} catch (StandbyException se) {
|
|
@@ -2464,7 +2501,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
* client to "try again later".
|
|
|
*/
|
|
|
LocatedBlock getAdditionalBlock(String src, long fileId, String clientName,
|
|
|
- ExtendedBlock previous, HashMap<Node, Node> excludedNodes,
|
|
|
+ ExtendedBlock previous, Set<Node> excludedNodes,
|
|
|
List<String> favoredNodes)
|
|
|
throws LeaseExpiredException, NotReplicatedYetException,
|
|
|
QuotaExceededException, SafeModeException, UnresolvedLinkException,
|
|
@@ -2567,9 +2604,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
checkBlock(previous);
|
|
|
onRetryBlock[0] = null;
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot add block to " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot add block to " + src);
|
|
|
|
|
|
// have we exceeded the configured limit of fs objects.
|
|
|
checkFsObjectLimit();
|
|
@@ -2663,7 +2698,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
|
|
|
/** @see NameNode#getAdditionalDatanode(String, ExtendedBlock, DatanodeInfo[], DatanodeInfo[], int, String) */
|
|
|
LocatedBlock getAdditionalDatanode(String src, final ExtendedBlock blk,
|
|
|
- final DatanodeInfo[] existings, final HashMap<Node, Node> excludes,
|
|
|
+ final DatanodeInfo[] existings, final Set<Node> excludes,
|
|
|
final int numAdditionalNodes, final String clientName
|
|
|
) throws IOException {
|
|
|
//check if the feature is enabled
|
|
@@ -2678,10 +2713,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
try {
|
|
|
checkOperation(OperationCategory.READ);
|
|
|
//check safe mode
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot add datanode; src=" + src
|
|
|
- + ", blk=" + blk, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot add datanode; src=" + src + ", blk=" + blk);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
|
|
|
//check lease
|
|
@@ -2726,10 +2758,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot abandon block " + b +
|
|
|
- " for fle" + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot abandon block " + b + " for fle" + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
|
|
|
//
|
|
@@ -2812,9 +2841,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot complete file " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot complete file " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
success = completeFileInternal(src, holder,
|
|
|
ExtendedBlock.getLocalBlock(last), fileId);
|
|
@@ -2990,9 +3017,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot rename " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot rename " + src);
|
|
|
src = FSDirectory.resolvePath(src, srcComponents, dir);
|
|
|
dst = FSDirectory.resolvePath(dst, dstComponents, dir);
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -3042,10 +3067,6 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
/** Rename src to dst */
|
|
|
void renameTo(String src, String dst, Options.Rename... options)
|
|
|
throws IOException, UnresolvedLinkException {
|
|
|
- CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
- if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
- return; // Return previous response
|
|
|
- }
|
|
|
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
|
|
NameNode.stateChangeLog.debug("DIR* NameSystem.renameTo: with options - "
|
|
|
+ src + " to " + dst);
|
|
@@ -3053,8 +3074,13 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
if (!DFSUtil.isValidName(dst)) {
|
|
|
throw new InvalidPathException("Invalid name: " + dst);
|
|
|
}
|
|
|
- FSPermissionChecker pc = getPermissionChecker();
|
|
|
+ final FSPermissionChecker pc = getPermissionChecker();
|
|
|
+
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
+ CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
+ if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
+ return; // Return previous response
|
|
|
+ }
|
|
|
byte[][] srcComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
|
|
byte[][] dstComponents = FSDirectory.getPathComponentsForReservedPath(dst);
|
|
|
HdfsFileStatus resultingStat = null;
|
|
@@ -3062,9 +3088,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot rename " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot rename " + src);
|
|
|
src = FSDirectory.resolvePath(src, srcComponents, dir);
|
|
|
dst = FSDirectory.resolvePath(dst, dstComponents, dir);
|
|
|
renameToInternal(pc, src, dst, cacheEntry != null, options);
|
|
@@ -3170,9 +3194,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot delete " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot delete " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
if (!recursive && dir.isNonEmptyDirectory(src)) {
|
|
|
throw new IOException(src + " is non empty");
|
|
@@ -3391,9 +3413,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot create directory " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot create directory " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
status = mkdirsInternal(pc, src, permissions, createParent);
|
|
|
if (status) {
|
|
@@ -3493,9 +3513,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot set quota on " + path, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot set quota on " + path);
|
|
|
dir.setQuota(path, nsQuota, dsQuota);
|
|
|
} finally {
|
|
|
writeUnlock();
|
|
@@ -3518,9 +3536,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot fsync file " + src, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot fsync file " + src);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
INodeFileUnderConstruction pendingFile = checkLease(src, clientName);
|
|
|
if (lastBlockLength > 0) {
|
|
@@ -3724,6 +3740,39 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
BlockInfo getStoredBlock(Block block) {
|
|
|
return blockManager.getStoredBlock(block);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean isInSnapshot(BlockInfoUnderConstruction blockUC) {
|
|
|
+ assert hasReadOrWriteLock();
|
|
|
+ final BlockCollection bc = blockUC.getBlockCollection();
|
|
|
+ if (bc == null || !(bc instanceof INodeFileUnderConstruction)) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ INodeFileUnderConstruction inodeUC = (INodeFileUnderConstruction) blockUC
|
|
|
+ .getBlockCollection();
|
|
|
+ String fullName = inodeUC.getName();
|
|
|
+ try {
|
|
|
+ if (fullName != null && fullName.startsWith(Path.SEPARATOR)
|
|
|
+ && dir.getINode(fullName) == inodeUC) {
|
|
|
+ // If file exists in normal path then no need to look in snapshot
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } catch (UnresolvedLinkException e) {
|
|
|
+ LOG.error("Error while resolving the link : " + fullName, e);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ /*
|
|
|
+ * 1. if bc is an instance of INodeFileUnderConstructionWithSnapshot, and
|
|
|
+ * bc is not in the current fsdirectory tree, bc must represent a snapshot
|
|
|
+ * file.
|
|
|
+ * 2. if fullName is not an absolute path, bc cannot be existent in the
|
|
|
+ * current fsdirectory tree.
|
|
|
+ * 3. if bc is not the current node associated with fullName, bc must be a
|
|
|
+ * snapshot inode.
|
|
|
+ */
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
void commitBlockSynchronization(ExtendedBlock lastblock,
|
|
|
long newgenerationstamp, long newlength,
|
|
@@ -3745,11 +3794,8 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
// If a DN tries to commit to the standby, the recovery will
|
|
|
// fail, and the next retry will succeed on the new NN.
|
|
|
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException(
|
|
|
- "Cannot commitBlockSynchronization while in safe mode",
|
|
|
- safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode(
|
|
|
+ "Cannot commitBlockSynchronization while in safe mode");
|
|
|
final BlockInfo storedBlock = getStoredBlock(
|
|
|
ExtendedBlock.getLocalBlock(lastblock));
|
|
|
if (storedBlock == null) {
|
|
@@ -3895,9 +3941,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot renew lease for " + holder, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot renew lease for " + holder);
|
|
|
leaseManager.renewLease(holder);
|
|
|
} finally {
|
|
|
writeUnlock();
|
|
@@ -3934,11 +3978,27 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
FSPermissionChecker pc = getPermissionChecker();
|
|
|
checkOperation(OperationCategory.READ);
|
|
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
|
|
+ String startAfterString = new String(startAfter);
|
|
|
readLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.READ);
|
|
|
src = FSDirectory.resolvePath(src, pathComponents, dir);
|
|
|
|
|
|
+ // Get file name when startAfter is an INodePath
|
|
|
+ if (FSDirectory.isReservedName(startAfterString)) {
|
|
|
+ byte[][] startAfterComponents = FSDirectory
|
|
|
+ .getPathComponentsForReservedPath(startAfterString);
|
|
|
+ try {
|
|
|
+ String tmp = FSDirectory.resolvePath(src, startAfterComponents, dir);
|
|
|
+ byte[][] regularPath = INode.getPathComponents(tmp);
|
|
|
+ startAfter = regularPath[regularPath.length - 1];
|
|
|
+ } catch (IOException e) {
|
|
|
+ // Possibly the inode is deleted
|
|
|
+ throw new DirectoryListingStartAfterNotFoundException(
|
|
|
+ "Can't find startAfter " + startAfterString);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if (isPermissionEnabled) {
|
|
|
if (dir.isDir(src)) {
|
|
|
checkPathAccess(pc, src, FsAction.READ_EXECUTE);
|
|
@@ -4220,6 +4280,14 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
return this.snapshotManager.getNumSnapshots();
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public String getSnapshotStats() {
|
|
|
+ Map<String, Object> info = new HashMap<String, Object>();
|
|
|
+ info.put("SnapshottableDirectories", this.getNumSnapshottableDirs());
|
|
|
+ info.put("Snapshots", this.getNumSnapshots());
|
|
|
+ return JSON.toString(info);
|
|
|
+ }
|
|
|
+
|
|
|
int getNumberOfDatanodes(DatanodeReportType type) {
|
|
|
readLock();
|
|
|
try {
|
|
@@ -4259,19 +4327,20 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
* @throws IOException if
|
|
|
*/
|
|
|
void saveNamespace() throws AccessControlException, IOException {
|
|
|
+ checkOperation(OperationCategory.UNCHECKED);
|
|
|
+ checkSuperuserPrivilege();
|
|
|
+
|
|
|
CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
return; // Return previous response
|
|
|
}
|
|
|
- checkSuperuserPrivilege();
|
|
|
- checkOperation(OperationCategory.UNCHECKED);
|
|
|
boolean success = false;
|
|
|
readLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.UNCHECKED);
|
|
|
if (!isInSafeMode()) {
|
|
|
- throw new IOException("Safe mode should be turned ON " +
|
|
|
- "in order to create namespace image.");
|
|
|
+ throw new IOException("Safe mode should be turned ON "
|
|
|
+ + "in order to create namespace image.");
|
|
|
}
|
|
|
getFSImage().saveNamespace(this);
|
|
|
success = true;
|
|
@@ -4348,7 +4417,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
* replicas, and calculates the ratio of safe blocks to the total number
|
|
|
* of blocks in the system, which is the size of blocks in
|
|
|
* {@link FSNamesystem#blockManager}. When the ratio reaches the
|
|
|
- * {@link #threshold} it starts the {@link SafeModeMonitor} daemon in order
|
|
|
+ * {@link #threshold} it starts the SafeModeMonitor daemon in order
|
|
|
* to monitor whether the safe mode {@link #extension} is passed.
|
|
|
* Then it leaves safe mode and destroys itself.
|
|
|
* <p>
|
|
@@ -4356,10 +4425,9 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
* not tracked because the name node is not intended to leave safe mode
|
|
|
* automatically in the case.
|
|
|
*
|
|
|
- * @see ClientProtocol#setSafeMode(HdfsConstants.SafeModeAction)
|
|
|
- * @see SafeModeMonitor
|
|
|
+ * @see ClientProtocol#setSafeMode(HdfsConstants.SafeModeAction, boolean)
|
|
|
*/
|
|
|
- class SafeModeInfo {
|
|
|
+ public class SafeModeInfo {
|
|
|
// configuration fields
|
|
|
/** Safe mode threshold condition %.*/
|
|
|
private double threshold;
|
|
@@ -4572,7 +4640,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
*/
|
|
|
private boolean needEnter() {
|
|
|
return (threshold != 0 && blockSafe < blockThreshold) ||
|
|
|
- (getNumLiveDataNodes() < datanodeThreshold) ||
|
|
|
+ (datanodeThreshold != 0 && getNumLiveDataNodes() < datanodeThreshold) ||
|
|
|
(!nameNodeHasResourcesAvailable());
|
|
|
}
|
|
|
|
|
@@ -5101,9 +5169,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.JOURNAL);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Log not rolled", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Log not rolled");
|
|
|
LOG.info("Roll Edit Log from " + Server.getRemoteAddress());
|
|
|
return getFSImage().rollEditLog();
|
|
|
} finally {
|
|
@@ -5124,9 +5190,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
try {
|
|
|
checkOperation(OperationCategory.CHECKPOINT);
|
|
|
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Checkpoint not started", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Checkpoint not started");
|
|
|
LOG.info("Start checkpoint for " + backupNode.getAddress());
|
|
|
cmd = getFSImage().startCheckpoint(backupNode, activeNamenode);
|
|
|
getEditLog().logSync();
|
|
@@ -5150,19 +5214,17 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
|
|
|
void endCheckpoint(NamenodeRegistration registration,
|
|
|
CheckpointSignature sig) throws IOException {
|
|
|
+ checkOperation(OperationCategory.CHECKPOINT);
|
|
|
CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
return; // Return previous response
|
|
|
}
|
|
|
- checkOperation(OperationCategory.CHECKPOINT);
|
|
|
boolean success = false;
|
|
|
readLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.CHECKPOINT);
|
|
|
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Checkpoint not ended", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Checkpoint not ended");
|
|
|
LOG.info("End checkpoint for " + registration.getAddress());
|
|
|
getFSImage().endCheckpoint(sig);
|
|
|
success = true;
|
|
@@ -5263,7 +5325,8 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
/**
|
|
|
* Get the total number of objects in the system.
|
|
|
*/
|
|
|
- long getMaxObjects() {
|
|
|
+ @Override // FSNamesystemMBean
|
|
|
+ public long getMaxObjects() {
|
|
|
return maxFsObjects;
|
|
|
}
|
|
|
|
|
@@ -5408,7 +5471,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
@Override // FSNamesystemMBean
|
|
|
public int getNumDecomDeadDataNodes() {
|
|
|
final List<DatanodeDescriptor> dead = new ArrayList<DatanodeDescriptor>();
|
|
|
- getBlockManager().getDatanodeManager().fetchDatanodes(dead, null, true);
|
|
|
+ getBlockManager().getDatanodeManager().fetchDatanodes(null, dead, true);
|
|
|
int deadDecommissioned = 0;
|
|
|
for (DatanodeDescriptor node : dead) {
|
|
|
deadDecommissioned += node.isDecommissioned() ? 1 : 0;
|
|
@@ -5416,6 +5479,12 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
return deadDecommissioned;
|
|
|
}
|
|
|
|
|
|
+ @Override // FSNamesystemMBean
|
|
|
+ public int getNumDecommissioningDataNodes() {
|
|
|
+ return getBlockManager().getDatanodeManager().getDecommissioningNodes()
|
|
|
+ .size();
|
|
|
+ }
|
|
|
+
|
|
|
@Override // FSNamesystemMBean
|
|
|
@Metric({"StaleDataNodes",
|
|
|
"Number of datanodes marked stale due to delayed heartbeat"})
|
|
@@ -5514,10 +5583,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
long nextGenerationStamp(boolean legacyBlock)
|
|
|
throws IOException, SafeModeException {
|
|
|
assert hasWriteLock();
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException(
|
|
|
- "Cannot get next generation stamp", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot get next generation stamp");
|
|
|
|
|
|
long gs;
|
|
|
if (legacyBlock) {
|
|
@@ -5570,12 +5636,9 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
/**
|
|
|
* Increments, logs and then returns the block ID
|
|
|
*/
|
|
|
- private long nextBlockId() throws SafeModeException {
|
|
|
+ private long nextBlockId() throws IOException {
|
|
|
assert hasWriteLock();
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException(
|
|
|
- "Cannot get next block ID", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot get next block ID");
|
|
|
final long blockId = blockIdGenerator.nextValue();
|
|
|
getEditLog().logAllocateBlockId(blockId);
|
|
|
// NB: callers sync the log
|
|
@@ -5585,10 +5648,8 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
private INodeFileUnderConstruction checkUCBlock(ExtendedBlock block,
|
|
|
String clientName) throws IOException {
|
|
|
assert hasWriteLock();
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot get a new generation stamp and an " +
|
|
|
- "access token for block " + block, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot get a new generation stamp and an "
|
|
|
+ + "access token for block " + block);
|
|
|
|
|
|
// check stored block state
|
|
|
BlockInfo storedBlock = getStoredBlock(ExtendedBlock.getLocalBlock(block));
|
|
@@ -5686,11 +5747,11 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
void updatePipeline(String clientName, ExtendedBlock oldBlock,
|
|
|
ExtendedBlock newBlock, DatanodeID[] newNodes)
|
|
|
throws IOException {
|
|
|
+ checkOperation(OperationCategory.WRITE);
|
|
|
CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
return; // Return previous response
|
|
|
}
|
|
|
- checkOperation(OperationCategory.WRITE);
|
|
|
LOG.info("updatePipeline(block=" + oldBlock
|
|
|
+ ", newGenerationStamp=" + newBlock.getGenerationStamp()
|
|
|
+ ", newLength=" + newBlock.getNumBytes()
|
|
@@ -5701,9 +5762,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
boolean success = false;
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Pipeline not updated", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Pipeline not updated");
|
|
|
assert newBlock.getBlockId()==oldBlock.getBlockId() : newBlock + " and "
|
|
|
+ oldBlock + " has different block identifier";
|
|
|
updatePipelineInternal(clientName, oldBlock, newBlock, newNodes,
|
|
@@ -5963,9 +6022,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot issue delegation token", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot issue delegation token");
|
|
|
if (!isAllowedDelegationTokenOp()) {
|
|
|
throw new IOException(
|
|
|
"Delegation Token can be issued only with kerberos or web authentication");
|
|
@@ -6010,9 +6067,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot renew delegation token", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot renew delegation token");
|
|
|
if (!isAllowedDelegationTokenOp()) {
|
|
|
throw new IOException(
|
|
|
"Delegation Token can be renewed only with kerberos or web authentication");
|
|
@@ -6043,9 +6098,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot cancel delegation token", safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot cancel delegation token");
|
|
|
String canceller = getRemoteUser().getUserName();
|
|
|
DelegationTokenIdentifier id = dtSecretManager
|
|
|
.cancelToken(token, canceller);
|
|
@@ -6271,14 +6324,25 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
final List<DatanodeDescriptor> live = new ArrayList<DatanodeDescriptor>();
|
|
|
blockManager.getDatanodeManager().fetchDatanodes(live, null, true);
|
|
|
for (DatanodeDescriptor node : live) {
|
|
|
- final Map<String, Object> innerinfo = new HashMap<String, Object>();
|
|
|
- innerinfo.put("lastContact", getLastContact(node));
|
|
|
- innerinfo.put("usedSpace", getDfsUsed(node));
|
|
|
- innerinfo.put("adminState", node.getAdminState().toString());
|
|
|
- innerinfo.put("nonDfsUsedSpace", node.getNonDfsUsed());
|
|
|
- innerinfo.put("capacity", node.getCapacity());
|
|
|
- innerinfo.put("numBlocks", node.numBlocks());
|
|
|
- innerinfo.put("version", node.getSoftwareVersion());
|
|
|
+ Map<String, Object> innerinfo = ImmutableMap.<String, Object>builder()
|
|
|
+ .put("infoAddr", node.getInfoAddr())
|
|
|
+ .put("infoSecureAddr", node.getInfoSecureAddr())
|
|
|
+ .put("xferaddr", node.getXferAddr())
|
|
|
+ .put("lastContact", getLastContact(node))
|
|
|
+ .put("usedSpace", getDfsUsed(node))
|
|
|
+ .put("adminState", node.getAdminState().toString())
|
|
|
+ .put("nonDfsUsedSpace", node.getNonDfsUsed())
|
|
|
+ .put("capacity", node.getCapacity())
|
|
|
+ .put("numBlocks", node.numBlocks())
|
|
|
+ .put("version", node.getSoftwareVersion())
|
|
|
+ .put("used", node.getDfsUsed())
|
|
|
+ .put("remaining", node.getRemaining())
|
|
|
+ .put("blockScheduled", node.getBlocksScheduled())
|
|
|
+ .put("blockPoolUsed", node.getBlockPoolUsed())
|
|
|
+ .put("blockPoolUsedPercent", node.getBlockPoolUsedPercent())
|
|
|
+ .put("volfails", node.getVolumeFailures())
|
|
|
+ .build();
|
|
|
+
|
|
|
info.put(node.getHostName(), innerinfo);
|
|
|
}
|
|
|
return JSON.toString(info);
|
|
@@ -6295,9 +6359,11 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
final List<DatanodeDescriptor> dead = new ArrayList<DatanodeDescriptor>();
|
|
|
blockManager.getDatanodeManager().fetchDatanodes(null, dead, true);
|
|
|
for (DatanodeDescriptor node : dead) {
|
|
|
- final Map<String, Object> innerinfo = new HashMap<String, Object>();
|
|
|
- innerinfo.put("lastContact", getLastContact(node));
|
|
|
- innerinfo.put("decommissioned", node.isDecommissioned());
|
|
|
+ Map<String, Object> innerinfo = ImmutableMap.<String, Object>builder()
|
|
|
+ .put("lastContact", getLastContact(node))
|
|
|
+ .put("decommissioned", node.isDecommissioned())
|
|
|
+ .put("xferaddr", node.getXferAddr())
|
|
|
+ .build();
|
|
|
info.put(node.getHostName(), innerinfo);
|
|
|
}
|
|
|
return JSON.toString(info);
|
|
@@ -6314,13 +6380,16 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
final List<DatanodeDescriptor> decomNodeList = blockManager.getDatanodeManager(
|
|
|
).getDecommissioningNodes();
|
|
|
for (DatanodeDescriptor node : decomNodeList) {
|
|
|
- final Map<String, Object> innerinfo = new HashMap<String, Object>();
|
|
|
- innerinfo.put("underReplicatedBlocks", node.decommissioningStatus
|
|
|
- .getUnderReplicatedBlocks());
|
|
|
- innerinfo.put("decommissionOnlyReplicas", node.decommissioningStatus
|
|
|
- .getDecommissionOnlyReplicas());
|
|
|
- innerinfo.put("underReplicateInOpenFiles", node.decommissioningStatus
|
|
|
- .getUnderReplicatedInOpenFiles());
|
|
|
+ Map<String, Object> innerinfo = ImmutableMap
|
|
|
+ .<String, Object> builder()
|
|
|
+ .put("xferaddr", node.getXferAddr())
|
|
|
+ .put("underReplicatedBlocks",
|
|
|
+ node.decommissioningStatus.getUnderReplicatedBlocks())
|
|
|
+ .put("decommissionOnlyReplicas",
|
|
|
+ node.decommissioningStatus.getDecommissionOnlyReplicas())
|
|
|
+ .put("underReplicateInOpenFiles",
|
|
|
+ node.decommissioningStatus.getUnderReplicatedInOpenFiles())
|
|
|
+ .build();
|
|
|
info.put(node.getHostName(), innerinfo);
|
|
|
}
|
|
|
return JSON.toString(info);
|
|
@@ -6514,11 +6583,17 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
* Verifies that the given identifier and password are valid and match.
|
|
|
* @param identifier Token identifier.
|
|
|
* @param password Password in the token.
|
|
|
- * @throws InvalidToken
|
|
|
*/
|
|
|
public synchronized void verifyToken(DelegationTokenIdentifier identifier,
|
|
|
- byte[] password) throws InvalidToken {
|
|
|
- getDelegationTokenSecretManager().verifyToken(identifier, password);
|
|
|
+ byte[] password) throws InvalidToken, RetriableException {
|
|
|
+ try {
|
|
|
+ getDelegationTokenSecretManager().verifyToken(identifier, password);
|
|
|
+ } catch (InvalidToken it) {
|
|
|
+ if (inTransitionToActive()) {
|
|
|
+ throw new RetriableException(it);
|
|
|
+ }
|
|
|
+ throw it;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -6535,6 +6610,11 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
return editLogTailer;
|
|
|
}
|
|
|
|
|
|
+ @VisibleForTesting
|
|
|
+ public void setEditLogTailerForTests(EditLogTailer tailer) {
|
|
|
+ this.editLogTailer = tailer;
|
|
|
+ }
|
|
|
+
|
|
|
@VisibleForTesting
|
|
|
void setFsLockForTests(ReentrantReadWriteLock lock) {
|
|
|
this.fsLock = lock;
|
|
@@ -6570,10 +6650,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot allow snapshot for " + path,
|
|
|
- safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot allow snapshot for " + path);
|
|
|
checkSuperuserPrivilege();
|
|
|
|
|
|
dir.writeLock();
|
|
@@ -6598,10 +6675,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot disallow snapshot for " + path,
|
|
|
- safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot disallow snapshot for " + path);
|
|
|
checkSuperuserPrivilege();
|
|
|
|
|
|
dir.writeLock();
|
|
@@ -6628,20 +6702,18 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
*/
|
|
|
String createSnapshot(String snapshotRoot, String snapshotName)
|
|
|
throws SafeModeException, IOException {
|
|
|
+ checkOperation(OperationCategory.WRITE);
|
|
|
+ final FSPermissionChecker pc = getPermissionChecker();
|
|
|
CacheEntryWithPayload cacheEntry = RetryCache.waitForCompletion(retryCache,
|
|
|
null);
|
|
|
if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
return (String) cacheEntry.getPayload();
|
|
|
}
|
|
|
- final FSPermissionChecker pc = getPermissionChecker();
|
|
|
writeLock();
|
|
|
String snapshotPath = null;
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot create snapshot for "
|
|
|
- + snapshotRoot, safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot create snapshot for " + snapshotRoot);
|
|
|
if (isPermissionEnabled) {
|
|
|
checkOwner(pc, snapshotRoot);
|
|
|
}
|
|
@@ -6680,19 +6752,17 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
*/
|
|
|
void renameSnapshot(String path, String snapshotOldName,
|
|
|
String snapshotNewName) throws SafeModeException, IOException {
|
|
|
+ checkOperation(OperationCategory.WRITE);
|
|
|
+ final FSPermissionChecker pc = getPermissionChecker();
|
|
|
CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
return; // Return previous response
|
|
|
}
|
|
|
- final FSPermissionChecker pc = getPermissionChecker();
|
|
|
writeLock();
|
|
|
boolean success = false;
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException("Cannot rename snapshot for " + path,
|
|
|
- safeMode);
|
|
|
- }
|
|
|
+ checkNameNodeSafeMode("Cannot rename snapshot for " + path);
|
|
|
if (isPermissionEnabled) {
|
|
|
checkOwner(pc, path);
|
|
|
}
|
|
@@ -6725,10 +6795,10 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
public SnapshottableDirectoryStatus[] getSnapshottableDirListing()
|
|
|
throws IOException {
|
|
|
SnapshottableDirectoryStatus[] status = null;
|
|
|
+ final FSPermissionChecker checker = getPermissionChecker();
|
|
|
readLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.READ);
|
|
|
- FSPermissionChecker checker = getPermissionChecker();
|
|
|
final String user = checker.isSuperUser()? null : checker.getUser();
|
|
|
status = snapshotManager.getSnapshottableDirListing(user);
|
|
|
} finally {
|
|
@@ -6796,21 +6866,21 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
*/
|
|
|
void deleteSnapshot(String snapshotRoot, String snapshotName)
|
|
|
throws SafeModeException, IOException {
|
|
|
+ checkOperation(OperationCategory.WRITE);
|
|
|
final FSPermissionChecker pc = getPermissionChecker();
|
|
|
+
|
|
|
CacheEntry cacheEntry = RetryCache.waitForCompletion(retryCache);
|
|
|
if (cacheEntry != null && cacheEntry.isSuccess()) {
|
|
|
return; // Return previous response
|
|
|
}
|
|
|
boolean success = false;
|
|
|
- checkOperation(OperationCategory.WRITE);
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
- if (isInSafeMode()) {
|
|
|
- throw new SafeModeException(
|
|
|
- "Cannot delete snapshot for " + snapshotRoot, safeMode);
|
|
|
+ checkNameNodeSafeMode("Cannot delete snapshot for " + snapshotRoot);
|
|
|
+ if (isPermissionEnabled) {
|
|
|
+ checkOwner(pc, snapshotRoot);
|
|
|
}
|
|
|
- checkOwner(pc, snapshotRoot);
|
|
|
|
|
|
BlocksMapUpdateInfo collectedBlocks = new BlocksMapUpdateInfo();
|
|
|
List<INode> removedINodes = new ChunkedArrayList<INode>();
|
|
@@ -7113,8 +7183,11 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
}
|
|
|
sb.append(trackingId);
|
|
|
}
|
|
|
- auditLog.info(sb);
|
|
|
+ logAuditMessage(sb.toString());
|
|
|
}
|
|
|
}
|
|
|
+ public void logAuditMessage(String message) {
|
|
|
+ auditLog.info(message);
|
|
|
+ }
|
|
|
}
|
|
|
}
|