Author: suresh
Date: Fri Sep 2 20:04:23 2011
New Revision: 1164683
URL: http://svn.apache.org/viewvc?rev=1164683&view=rev
Log:
Porting patch from 0.20-append - HDFS-988. Fix bug where savenameSpace can
corrupt edits log. Contributed by Nicolas Spiegelberg.
Modified:
hadoop/common/branches/branch-0.20-security/CHANGES.txt
hadoop/common/branches/branch-0.20-security/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
Modified: hadoop/common/branches/branch-0.20-security/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/CHANGES.txt?rev=1164683&r1=1164682&r2=1164683&view=diff
==============================================================================
--- hadoop/common/branches/branch-0.20-security/CHANGES.txt (original)
+++ hadoop/common/branches/branch-0.20-security/CHANGES.txt Fri Sep 2 20:04:23
2011
@@ -50,6 +50,9 @@ Release 0.20.205.0 - unreleased
HDFS-1118. Fix socketleak on DFSClient.
(Zheng Shao via dhruba)
+ HDFS-988. Fix bug where savenameSpace can corrupt edits log.
+ (Nicolas Spiegelberg via dhruba)
+
IMPROVEMENTS
MAPREDUCE-2187. Reporter sends progress during sort/merge. (Anupam Seth via
Modified:
hadoop/common/branches/branch-0.20-security/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
URL:
http://svn.apache.org/viewvc/hadoop/common/branches/branch-0.20-security/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java?rev=1164683&r1=1164682&r2=1164683&view=diff
==============================================================================
---
hadoop/common/branches/branch-0.20-security/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
(original)
+++
hadoop/common/branches/branch-0.20-security/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
Fri Sep 2 20:04:23 2011
@@ -548,7 +548,7 @@ public class FSNamesystem implements FSC
return fsNamesystemObject;
}
- NamespaceInfo getNamespaceInfo() {
+ synchronized NamespaceInfo getNamespaceInfo() {
return new NamespaceInfo(dir.fsImage.getNamespaceID(),
dir.fsImage.getCTime(),
getDistributedUpgradeVersion());
@@ -833,12 +833,14 @@ public class FSNamesystem implements FSC
* Set permissions for an existing file.
* @throws IOException
*/
- public synchronized void setPermission(String src, FsPermission permission
+ public void setPermission(String src, FsPermission permission
) throws IOException {
- if (isInSafeMode())
- throw new SafeModeException("Cannot set permission for " + src,
safeMode);
- checkOwner(src);
- dir.setPermission(src, permission);
+ synchronized (this) {
+ if (isInSafeMode())
+ throw new SafeModeException("Cannot set permission for " + src,
safeMode);
+ checkOwner(src);
+ dir.setPermission(src, permission);
+ }
getEditLog().logSync();
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
final HdfsFileStatus stat = dir.getFileInfo(src);
@@ -852,21 +854,23 @@ public class FSNamesystem implements FSC
* Set owner for an existing file.
* @throws IOException
*/
- public synchronized void setOwner(String src, String username, String group
+ public void setOwner(String src, String username, String group
) throws IOException {
- if (isInSafeMode())
- throw new SafeModeException("Cannot set owner for " + src, safeMode);
- FSPermissionChecker pc = checkOwner(src);
- if (!pc.isSuper) {
- if (username != null && !pc.user.equals(username)) {
- throw new AccessControlException("Non-super user cannot change
owner.");
- }
- if (group != null && !pc.containsGroup(group)) {
- throw new AccessControlException("User does not belong to " + group
- + " .");
+ synchronized (this) {
+ if (isInSafeMode())
+ throw new SafeModeException("Cannot set owner for " + src, safeMode);
+ FSPermissionChecker pc = checkOwner(src);
+ if (!pc.isSuper) {
+ if (username != null && !pc.user.equals(username)) {
+ throw new AccessControlException("Non-super user cannot change
owner.");
+ }
+ if (group != null && !pc.containsGroup(group)) {
+ throw new AccessControlException("User does not belong to " + group
+ + " .");
+ }
}
+ dir.setOwner(src, username, group);
}
- dir.setOwner(src, username, group);
getEditLog().logSync();
if (auditLog.isInfoEnabled() && isExternalInvocation()) {
final HdfsFileStatus stat = dir.getFileInfo(src);
@@ -1022,6 +1026,9 @@ public class FSNamesystem implements FSC
throw new IOException("Access time for hdfs is not configured. " +
" Please set dfs.support.accessTime configuration
parameter.");
}
+ if (isInSafeMode()) {
+ throw new SafeModeException("Cannot set accesstimes for " + src,
safeMode);
+ }
//
// The caller needs to have write access to set access & modification
times.
if (isPermissionEnabled) {
@@ -1409,10 +1416,6 @@ public class FSNamesystem implements FSC
+src+" for "+clientName);
synchronized (this) {
- if (isInSafeMode()) {
- throw new SafeModeException("Cannot add block to " + src, safeMode);
- }
-
// have we exceeded the configured limit of fs objects.
checkFsObjectLimit();
@@ -1443,6 +1446,9 @@ public class FSNamesystem implements FSC
// Allocate a new block and record it in the INode.
synchronized (this) {
+ if (isInSafeMode()) {
+ throw new SafeModeException("Cannot add block to " + src, safeMode);
+ }
INode[] pathINodes = dir.getExistingPathINodes(src);
int inodesLen = pathINodes.length;
checkLease(src, clientName, pathINodes[inodesLen-1]);
@@ -1481,6 +1487,10 @@ public class FSNamesystem implements FSC
//
NameNode.stateChangeLog.debug("BLOCK* NameSystem.abandonBlock: "
+b+"of file "+src);
+ if (isInSafeMode()) {
+ throw new SafeModeException("Cannot abandon block " + b +
+ " for fle" + src, safeMode);
+ }
INodeFileUnderConstruction file = checkLease(src, holder);
dir.removeBlock(src, file, b);
NameNode.stateChangeLog.debug("BLOCK* NameSystem.abandonBlock: "
@@ -1764,7 +1774,7 @@ public class FSNamesystem implements FSC
/**
* Invalidates the given block on the given datanode.
*/
- public synchronized void invalidateBlock(Block blk, DatanodeInfo dn)
+ private synchronized void invalidateBlock(Block blk, DatanodeInfo dn)
throws IOException {
NameNode.stateChangeLog.info("DIR* NameSystem.invalidateBlock: "
+ blk + " on "
@@ -1963,13 +1973,15 @@ public class FSNamesystem implements FSC
* contract.
*/
void setQuota(String path, long nsQuota, long dsQuota) throws IOException {
- if (isInSafeMode())
- throw new SafeModeException("Cannot set quota on " + path, safeMode);
- if (isPermissionEnabled) {
- checkSuperuserPrivilege();
- }
+ synchronized (this) {
+ if (isInSafeMode())
+ throw new SafeModeException("Cannot set quota on " + path, safeMode);
+ if (isPermissionEnabled) {
+ checkSuperuserPrivilege();
+ }
- dir.setQuota(path, nsQuota, dsQuota);
+ dir.setQuota(path, nsQuota, dsQuota);
+ }
getEditLog().logSync();
}
@@ -1989,6 +2001,7 @@ public class FSNamesystem implements FSC
INodeFileUnderConstruction pendingFile = checkLease(src, clientName);
dir.persistBlocks(src, pendingFile);
}
+ getEditLog().logSync();
}
/**
@@ -2079,7 +2092,7 @@ public class FSNamesystem implements FSC
checkReplicationFactor(newFile);
}
- synchronized void commitBlockSynchronization(Block lastblock,
+ public void commitBlockSynchronization(Block lastblock,
long newgenerationstamp, long newlength,
boolean closeFile, boolean deleteblock, DatanodeID[] newtargets
) throws IOException {
@@ -2090,6 +2103,12 @@ public class FSNamesystem implements FSC
+ ", closeFile=" + closeFile
+ ", deleteBlock=" + deleteblock
+ ")");
+ String src = null;
+ synchronized (this) {
+ if (isInSafeMode()) {
+ throw new SafeModeException("Cannot commitBlockSynchronization "
+ + lastblock, safeMode);
+ }
final BlockInfo oldblockinfo = blocksMap.getStoredBlock(lastblock);
if (oldblockinfo == null) {
throw new IOException("Block (=" + lastblock + ") not found");
@@ -2132,7 +2151,7 @@ public class FSNamesystem implements FSC
// If this commit does not want to close the file, persist
// blocks only if append is supported and return
- String src = leaseManager.findPath(pendingFile);
+ src = leaseManager.findPath(pendingFile);
if (!closeFile) {
if (supportAppends) {
dir.persistBlocks(src, pendingFile);
@@ -2144,6 +2163,8 @@ public class FSNamesystem implements FSC
//remove lease, close file
finalizeINodeFileUnderConstruction(src, pendingFile);
+ } // end of synchronized section
+
getEditLog().logSync();
LOG.info("commitBlockSynchronization(newblock=" + lastblock
+ ", file=" + src
@@ -2156,7 +2177,7 @@ public class FSNamesystem implements FSC
/**
* Renew the lease(s) held by the given client
*/
- void renewLease(String holder) throws IOException {
+ synchronized void renewLease(String holder) throws IOException {
if (isInSafeMode())
throw new SafeModeException("Cannot renew lease for " + holder,
safeMode);
leaseManager.renewLease(holder);
@@ -2846,7 +2867,7 @@ public class FSNamesystem implements FSC
+ "Removing block " + block
+ " from neededReplications as it has enough replicas.");
return false;
- }
+ }
// Add block to the to be replicated list
srcNode.addBlockToBeReplicated(block, targets);
@@ -4764,6 +4785,7 @@ public class FSNamesystem implements FSC
return;
}
safeMode.setManual();
+ getEditLog().logSync();
NameNode.stateChangeLog.info("STATE* Safe mode is ON. "
+ safeMode.getTurnOffTip());
}
@@ -5048,7 +5070,7 @@ public class FSNamesystem implements FSC
/**
* Increments, logs and then returns the stamp
*/
- long nextGenerationStamp() {
+ private long nextGenerationStamp() {
long gs = generationStamp.nextStamp();
getEditLog().logGenerationStamp(gs);
return gs;
@@ -5059,6 +5081,9 @@ public class FSNamesystem implements FSC
* Increments, logs and then returns the stamp
*/
synchronized long nextGenerationStampForBlock(Block block) throws
IOException {
+ if (isInSafeMode()) {
+ throw new SafeModeException("Cannot get nextGenStamp for " + block,
safeMode);
+ }
BlockInfo storedBlock = blocksMap.getStoredBlock(block);
if (storedBlock == null) {
String msg = block + " is already commited, storedBlock == null.";