|
@@ -103,6 +103,7 @@ import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.locks.Condition;
|
|
|
import java.util.concurrent.locks.ReentrantLock;
|
|
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
|
@@ -514,6 +515,59 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
|
|
|
private final NNConf nnConf;
|
|
|
|
|
|
+ private volatile boolean imageLoaded = false;
|
|
|
+ private final Condition cond;
|
|
|
+ /**
|
|
|
+ * Notify that loading of this FSDirectory is complete, and
|
|
|
+ * it is imageLoaded for use
|
|
|
+ */
|
|
|
+ void imageLoadComplete() {
|
|
|
+ Preconditions.checkState(!imageLoaded, "FSDirectory already loaded");
|
|
|
+ setImageLoaded();
|
|
|
+ }
|
|
|
+
|
|
|
+ void setImageLoaded() {
|
|
|
+ if(imageLoaded) return;
|
|
|
+ writeLock();
|
|
|
+ try {
|
|
|
+ setImageLoaded(true);
|
|
|
+ dir.markNameCacheInitialized();
|
|
|
+ cond.signalAll();
|
|
|
+ } finally {
|
|
|
+ writeUnlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //This is for testing purposes only
|
|
|
+ @VisibleForTesting
|
|
|
+ boolean isImageLoaded() {
|
|
|
+ return imageLoaded;
|
|
|
+ }
|
|
|
+
|
|
|
+ // exposed for unit tests
|
|
|
+ protected void setImageLoaded(boolean flag) {
|
|
|
+ imageLoaded = flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Block until the object is imageLoaded to be used.
|
|
|
+ */
|
|
|
+ void waitForLoadingFSImage() {
|
|
|
+ if (!imageLoaded) {
|
|
|
+ writeLock();
|
|
|
+ try {
|
|
|
+ while (!imageLoaded) {
|
|
|
+ try {
|
|
|
+ cond.await(5000, TimeUnit.MILLISECONDS);
|
|
|
+ } catch (InterruptedException ignored) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ writeUnlock();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Set the last allocated inode id when fsimage or editlog is loaded.
|
|
|
*/
|
|
@@ -555,6 +609,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
inodeId.setCurrentValue(INodeId.LAST_RESERVED_ID);
|
|
|
snapshotManager.clearSnapshottableDirs();
|
|
|
cacheManager.clear();
|
|
|
+ setImageLoaded(false);
|
|
|
}
|
|
|
|
|
|
@VisibleForTesting
|
|
@@ -682,6 +737,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
boolean fair = conf.getBoolean("dfs.namenode.fslock.fair", true);
|
|
|
LOG.info("fsLock is fair:" + fair);
|
|
|
fsLock = new FSNamesystemLock(fair);
|
|
|
+ cond = fsLock.writeLock().newCondition();
|
|
|
try {
|
|
|
resourceRecheckInterval = conf.getLong(
|
|
|
DFS_NAMENODE_RESOURCE_CHECK_INTERVAL_KEY,
|
|
@@ -921,7 +977,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
}
|
|
|
writeUnlock();
|
|
|
}
|
|
|
- dir.imageLoadComplete();
|
|
|
+ imageLoadComplete();
|
|
|
}
|
|
|
|
|
|
private void startSecretManager() {
|
|
@@ -1840,6 +1896,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
HdfsFileStatus resultingStat = null;
|
|
|
FSPermissionChecker pc = getPermissionChecker();
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -2115,6 +2172,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
FSPermissionChecker pc = getPermissionChecker();
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -2242,6 +2300,8 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
|
|
boolean create = flag.contains(CreateFlag.CREATE);
|
|
|
boolean overwrite = flag.contains(CreateFlag.OVERWRITE);
|
|
|
+
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -2730,6 +2790,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
Block newBlock = null;
|
|
|
long offset;
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -2952,6 +3013,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
}
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -3050,6 +3112,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
boolean success = false;
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -3249,6 +3312,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
checkNameNodeSafeMode("Cannot rename " + src);
|
|
|
+ waitForLoadingFSImage();
|
|
|
src = FSDirectory.resolvePath(src, srcComponents, dir);
|
|
|
dst = FSDirectory.resolvePath(dst, dstComponents, dir);
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -3356,6 +3420,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
false);
|
|
|
}
|
|
|
|
|
|
+ waitForLoadingFSImage();
|
|
|
long mtime = now();
|
|
|
dir.renameTo(src, dst, mtime, options);
|
|
|
getEditLog().logRename(src, dst, mtime, logRetryCache, options);
|
|
@@ -3429,6 +3494,8 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
|
|
boolean ret = false;
|
|
|
+
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -3902,6 +3969,8 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
NameNode.stateChangeLog.info("BLOCK* fsync: " + src + " for " + clientName);
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
byte[][] pathComponents = FSDirectory.getPathComponentsForReservedPath(src);
|
|
|
+
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -4103,6 +4172,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
INodeFile pendingFile, int latestSnapshot) throws IOException,
|
|
|
UnresolvedLinkException {
|
|
|
assert hasWriteLock();
|
|
|
+
|
|
|
FileUnderConstructionFeature uc = pendingFile.getFileUnderConstructionFeature();
|
|
|
Preconditions.checkArgument(uc != null);
|
|
|
leaseManager.removeLease(uc.getClientName(), src);
|
|
@@ -4114,6 +4184,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
// since we just remove the uc feature from pendingFile
|
|
|
final INodeFile newFile = pendingFile.toCompleteFile(now());
|
|
|
|
|
|
+ waitForLoadingFSImage();
|
|
|
// close file and persist block allocations for this file
|
|
|
closeFile(src, newFile);
|
|
|
|
|
@@ -4172,6 +4243,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
+ ")");
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
|
String src = "";
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
try {
|
|
|
checkOperation(OperationCategory.WRITE);
|
|
@@ -4517,7 +4589,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
*/
|
|
|
private void closeFile(String path, INodeFile file) {
|
|
|
assert hasWriteLock();
|
|
|
- dir.waitForReady();
|
|
|
+ waitForLoadingFSImage();
|
|
|
// file is closed
|
|
|
getEditLog().logCloseFile(path, file);
|
|
|
if (NameNode.stateChangeLog.isDebugEnabled()) {
|
|
@@ -4541,7 +4613,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
boolean createParent, boolean logRetryCache)
|
|
|
throws UnresolvedLinkException, FileAlreadyExistsException,
|
|
|
QuotaExceededException, SnapshotAccessControlException, AclException {
|
|
|
- dir.waitForReady();
|
|
|
+ waitForLoadingFSImage();
|
|
|
|
|
|
final long modTime = now();
|
|
|
if (createParent) {
|
|
@@ -5804,7 +5876,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
boolean ignoreEmptyDir, boolean resolveLink)
|
|
|
throws AccessControlException, UnresolvedLinkException {
|
|
|
if (!pc.isSuperUser()) {
|
|
|
- dir.waitForReady();
|
|
|
+ waitForLoadingFSImage();
|
|
|
readLock();
|
|
|
try {
|
|
|
pc.checkPermission(path, dir, doCheckOwner, ancestorAccess,
|
|
@@ -6271,6 +6343,7 @@ public class FSNamesystem implements Namesystem, FSClusterStats,
|
|
|
+ ", newNodes=" + Arrays.asList(newNodes)
|
|
|
+ ", clientName=" + clientName
|
|
|
+ ")");
|
|
|
+ waitForLoadingFSImage();
|
|
|
writeLock();
|
|
|
boolean success = false;
|
|
|
try {
|