You are viewing a plain text version of this content. The canonical link for it is here.
Posted to hdfs-commits@hadoop.apache.org by to...@apache.org on 2011/06/06 07:28:33 UTC
svn commit: r1132527 - in /hadoop/hdfs/branches/branch-0.22: CHANGES.txt
src/java/org/apache/hadoop/hdfs/server/namenode/FSImage.java
src/test/hdfs/org/apache/hadoop/hdfs/TestDFSRollback.java
Author: todd
Date: Mon Jun 6 05:28:33 2011
New Revision: 1132527
URL: http://svn.apache.org/viewvc?rev=1132527&view=rev
Log:
HDFS-1969. Running rollback on new-version namenode destroys the namespace. Contributed by Todd Lipcon.
Modified:
hadoop/hdfs/branches/branch-0.22/CHANGES.txt
hadoop/hdfs/branches/branch-0.22/src/java/org/apache/hadoop/hdfs/server/namenode/FSImage.java
hadoop/hdfs/branches/branch-0.22/src/test/hdfs/org/apache/hadoop/hdfs/TestDFSRollback.java
Modified: hadoop/hdfs/branches/branch-0.22/CHANGES.txt
URL: http://svn.apache.org/viewvc/hadoop/hdfs/branches/branch-0.22/CHANGES.txt?rev=1132527&r1=1132526&r2=1132527&view=diff
==============================================================================
--- hadoop/hdfs/branches/branch-0.22/CHANGES.txt (original)
+++ hadoop/hdfs/branches/branch-0.22/CHANGES.txt Mon Jun 6 05:28:33 2011
@@ -555,6 +555,9 @@ Release 0.22.0 - Unreleased
HDFS-1936. Layout version change from HDFS-1822 causes upgrade failure.
(suresh)
+ HDFS-1969. Running rollback on new-version namenode destroys the
+ namespace. (todd)
+
Release 0.21.1 - Unreleased
IMPROVEMENTS
Modified: hadoop/hdfs/branches/branch-0.22/src/java/org/apache/hadoop/hdfs/server/namenode/FSImage.java
URL: http://svn.apache.org/viewvc/hadoop/hdfs/branches/branch-0.22/src/java/org/apache/hadoop/hdfs/server/namenode/FSImage.java?rev=1132527&r1=1132526&r2=1132527&view=diff
==============================================================================
--- hadoop/hdfs/branches/branch-0.22/src/java/org/apache/hadoop/hdfs/server/namenode/FSImage.java (original)
+++ hadoop/hdfs/branches/branch-0.22/src/java/org/apache/hadoop/hdfs/server/namenode/FSImage.java Mon Jun 6 05:28:33 2011
@@ -570,6 +570,14 @@ public class FSImage extends Storage {
}
StorageDirectory sdPrev = prevState.new StorageDirectory(sd.getRoot());
sdPrev.read(sdPrev.getPreviousVersionFile()); // read and verify consistency of the prev dir
+ if (prevState.getLayoutVersion() != FSConstants.LAYOUT_VERSION) {
+ throw new IOException(
+ "Cannot rollback to storage version " +
+ prevState.getLayoutVersion() +
+ " using this version of the NameNode, which uses storage version " +
+ FSConstants.LAYOUT_VERSION + ". " +
+ "Please use the previous version of HDFS to perform the rollback.");
+ }
canRollback = true;
}
if (!canRollback)
@@ -736,11 +744,15 @@ public class FSImage extends Storage {
props.setProperty("distributedUpgradeState", Boolean.toString(uState));
props.setProperty("distributedUpgradeVersion", Integer.toString(uVersion));
}
- if (imageDigest == null) {
- imageDigest = MD5Hash.digest(
- new FileInputStream(getImageFile(sd, NameNodeFile.IMAGE)));
+ if (LayoutVersion.supports(Feature.FSIMAGE_CHECKSUM, layoutVersion)) {
+ // Though the current NN supports this feature, this function
+ // is called with old layoutVersions from the upgrade tests.
+ if (imageDigest == null) {
+ imageDigest = MD5Hash.digest(
+ new FileInputStream(getImageFile(sd, NameNodeFile.IMAGE)));
+ }
+ props.setProperty(MESSAGE_DIGEST_PROPERTY, imageDigest.toString());
}
- props.setProperty(MESSAGE_DIGEST_PROPERTY, imageDigest.toString());
writeCheckpointTime(sd);
}
@@ -1285,6 +1297,11 @@ public class FSImage extends Storage {
* Save current image and empty journal into {@code current} directory.
*/
protected void saveCurrent(StorageDirectory sd) throws IOException {
+ if (getLayoutVersion() != FSConstants.LAYOUT_VERSION) {
+ throw new IllegalStateException(
+ "NN with storage version " + FSConstants.LAYOUT_VERSION +
+ "cannot save an image with version " + getLayoutVersion());
+ }
File curDir = sd.getCurrentDir();
NameNodeDirType dirType = (NameNodeDirType)sd.getStorageDirType();
// save new image or new edits
Modified: hadoop/hdfs/branches/branch-0.22/src/test/hdfs/org/apache/hadoop/hdfs/TestDFSRollback.java
URL: http://svn.apache.org/viewvc/hadoop/hdfs/branches/branch-0.22/src/test/hdfs/org/apache/hadoop/hdfs/TestDFSRollback.java?rev=1132527&r1=1132526&r2=1132527&view=diff
==============================================================================
--- hadoop/hdfs/branches/branch-0.22/src/test/hdfs/org/apache/hadoop/hdfs/TestDFSRollback.java (original)
+++ hadoop/hdfs/branches/branch-0.22/src/test/hdfs/org/apache/hadoop/hdfs/TestDFSRollback.java Mon Jun 6 05:28:33 2011
@@ -32,6 +32,7 @@ import org.apache.hadoop.fs.FileUtil;
import org.apache.hadoop.hdfs.server.common.StorageInfo;
import org.apache.hadoop.hdfs.server.common.HdfsConstants.NodeType;
import org.apache.hadoop.hdfs.server.common.HdfsConstants.StartupOption;
+import org.apache.hadoop.util.StringUtils;
/**
* This test ensures the appropriate response (successful or failure) from
@@ -89,7 +90,7 @@ public class TestDFSRollback extends Tes
* Attempts to start a NameNode with the given operation. Starting
* the NameNode should throw an exception.
*/
- void startNameNodeShouldFail(StartupOption operation) {
+ void startNameNodeShouldFail(StartupOption operation, String searchString) {
try {
cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0)
.startupOption(operation)
@@ -99,6 +100,10 @@ public class TestDFSRollback extends Tes
.build(); // should fail
throw new AssertionError("NameNode should have failed to start");
} catch (Exception expected) {
+ if (!expected.getMessage().contains(searchString)) {
+ fail("Expected substring '" + searchString + "' in exception " +
+ "but got: " + StringUtils.stringifyException(expected));
+ }
// expected
}
}
@@ -164,7 +169,8 @@ public class TestDFSRollback extends Tes
log("NameNode rollback without existing previous dir", numDirs);
UpgradeUtilities.createStorageDirs(NAME_NODE, nameNodeDirs, "current");
- startNameNodeShouldFail(StartupOption.ROLLBACK);
+ startNameNodeShouldFail(StartupOption.ROLLBACK,
+ "None of the storage directories contain previous fs state");
UpgradeUtilities.createEmptyDirs(nameNodeDirs);
log("DataNode rollback without existing previous dir", numDirs);
@@ -227,7 +233,8 @@ public class TestDFSRollback extends Tes
for (File f : baseDirs) {
FileUtil.fullyDelete(new File(f,"edits"));
}
- startNameNodeShouldFail(StartupOption.ROLLBACK);
+ startNameNodeShouldFail(StartupOption.ROLLBACK,
+ "Edits file is not found");
UpgradeUtilities.createEmptyDirs(nameNodeDirs);
log("NameNode rollback with no image file", numDirs);
@@ -236,7 +243,8 @@ public class TestDFSRollback extends Tes
for (File f : baseDirs) {
FileUtil.fullyDelete(new File(f,"fsimage"));
}
- startNameNodeShouldFail(StartupOption.ROLLBACK);
+ startNameNodeShouldFail(StartupOption.ROLLBACK,
+ "Image file is not found");
UpgradeUtilities.createEmptyDirs(nameNodeDirs);
log("NameNode rollback with corrupt version file", numDirs);
@@ -245,7 +253,8 @@ public class TestDFSRollback extends Tes
for (File f : baseDirs) {
UpgradeUtilities.corruptFile(new File(f,"VERSION"));
}
- startNameNodeShouldFail(StartupOption.ROLLBACK);
+ startNameNodeShouldFail(StartupOption.ROLLBACK,
+ "file VERSION is invalid");
UpgradeUtilities.createEmptyDirs(nameNodeDirs);
log("NameNode rollback with old layout version in previous", numDirs);
@@ -255,7 +264,8 @@ public class TestDFSRollback extends Tes
new StorageInfo(1,
UpgradeUtilities.getCurrentNamespaceID(null),
UpgradeUtilities.getCurrentFsscTime(null)));
- startNameNodeShouldFail(StartupOption.UPGRADE);
+ startNameNodeShouldFail(StartupOption.ROLLBACK,
+ "Cannot rollback to storage version 1 using this version");
UpgradeUtilities.createEmptyDirs(nameNodeDirs);
} // end numDir loop
}