From 2c04152f30e6b92d22fe55b59c36fcb9fd8e451c Mon Sep 17 00:00:00 2001 From: Eli Collins Date: Fri, 30 Mar 2012 00:14:13 +0000 Subject: [PATCH] HDFS-3137. svn merge -c 1307173 from trunk git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1307175 13f79535-47bb-0310-9956-ffa450edef68 --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 2 + .../blockmanagement/DatanodeDescriptor.java | 17 -- .../hadoop/hdfs/server/common/Storage.java | 12 +- .../hdfs/server/datanode/DataStorage.java | 88 ++---- .../hdfs/server/namenode/FSEditLogLoader.java | 41 +-- .../hdfs/server/namenode/FSEditLogOp.java | 140 +-------- .../server/namenode/FSEditLogOpCodes.java | 4 +- .../hdfs/server/namenode/FSImageFormat.java | 127 ++------- .../server/namenode/FSImageSerialization.java | 62 +--- .../hdfs/server/namenode/FSNamesystem.java | 8 - .../hadoop/hdfs/TestDFSUpgradeFromImage.java | 13 - .../server/common/TestDistributedUpgrade.java | 267 ------------------ .../TestOfflineEditsViewer.java | 3 +- .../src/test/resources/hadoop-14-dfs-dir.tgz | Bin 153081 -> 0 bytes .../src/test/resources/hadoop-dfs-dir.txt | 15 - 15 files changed, 75 insertions(+), 724 deletions(-) delete mode 100644 hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/common/TestDistributedUpgrade.java delete mode 100644 hadoop-hdfs-project/hadoop-hdfs/src/test/resources/hadoop-14-dfs-dir.tgz diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 8edb4b7e384..0f45fbf8936 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -8,6 +8,8 @@ Release 2.0.0 - UNRELEASED HDFS-2303. Unbundle jsvc. (Roman Shaposhnik and Mingjie Lai via eli) + HDFS-3137. Bump LAST_UPGRADABLE_LAYOUT_VERSION to -16. (eli) + NEW FEATURES HDFS-2978. The NameNode should expose name dir statuses via JMX. (atm) diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeDescriptor.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeDescriptor.java index 5c02546c5ba..bd1f056ace5 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeDescriptor.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/blockmanagement/DatanodeDescriptor.java @@ -440,23 +440,6 @@ public class DatanodeDescriptor extends DatanodeInfo { } } - /** Serialization for FSEditLog */ - public void readFieldsFromFSEditLog(DataInput in) throws IOException { - this.name = DeprecatedUTF8.readString(in); - this.storageID = DeprecatedUTF8.readString(in); - this.infoPort = in.readShort() & 0x0000ffff; - - this.capacity = in.readLong(); - this.dfsUsed = in.readLong(); - this.remaining = in.readLong(); - this.blockPoolUsed = in.readLong(); - this.lastUpdate = in.readLong(); - this.xceiverCount = in.readInt(); - this.location = Text.readString(in); - this.hostName = Text.readString(in); - setAdminState(WritableUtils.readEnum(in, AdminStates.class)); - } - /** * @return Approximate number of blocks currently scheduled to be written * to this datanode. diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java index c76d24c6a7f..5ed6e358867 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java @@ -64,18 +64,12 @@ import org.apache.hadoop.util.VersionInfo; public abstract class Storage extends StorageInfo { public static final Log LOG = LogFactory.getLog(Storage.class.getName()); - // Constants - // last layout version that did not support upgrades public static final int LAST_PRE_UPGRADE_LAYOUT_VERSION = -3; - // this corresponds to Hadoop-0.14. - public static final int LAST_UPGRADABLE_LAYOUT_VERSION = -7; - protected static final String LAST_UPGRADABLE_HADOOP_VERSION = "Hadoop-0.14"; - - /* this should be removed when LAST_UPGRADABLE_LV goes beyond -13. - * any upgrade code that uses this constant should also be removed. */ - public static final int PRE_GENERATIONSTAMP_LAYOUT_VERSION = -13; + // this corresponds to Hadoop-0.18 + public static final int LAST_UPGRADABLE_LAYOUT_VERSION = -16; + protected static final String LAST_UPGRADABLE_HADOOP_VERSION = "Hadoop-0.18"; /** Layout versions of 0.20.203 release */ public static final int[] LAYOUT_VERSIONS_203 = {-19, -31}; diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java index 16244c725bd..d3e3aa6630c 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/datanode/DataStorage.java @@ -73,9 +73,6 @@ public class DataStorage extends Storage { public final static String STORAGE_DIR_FINALIZED = "finalized"; public final static String STORAGE_DIR_TMP = "tmp"; - private static final Pattern PRE_GENSTAMP_META_FILE_PATTERN = - Pattern.compile("(.*blk_[-]*\\d+)\\.meta$"); - /** Access to this variable is guarded by "this" */ private String storageID; @@ -669,13 +666,6 @@ public class DataStorage extends Storage { in.close(); } } else { - - //check if we are upgrading from pre-generation stamp version. - if (oldLV >= PRE_GENERATIONSTAMP_LAYOUT_VERSION) { - // Link to the new file name. - to = new File(convertMetatadataFileName(to.getAbsolutePath())); - } - HardLink.createHardLink(from, to); hl.linkStats.countSingleLinks++; } @@ -687,50 +677,32 @@ public class DataStorage extends Storage { if (!to.mkdirs()) throw new IOException("Cannot create directory " + to); - //If upgrading from old stuff, need to munge the filenames. That has to - //be done one file at a time, so hardlink them one at a time (slow). - if (oldLV >= PRE_GENERATIONSTAMP_LAYOUT_VERSION) { - String[] blockNames = from.list(new java.io.FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith(BLOCK_SUBDIR_PREFIX) - || name.startsWith(BLOCK_FILE_PREFIX) - || name.startsWith(COPY_FILE_PREFIX); - } - }); - if (blockNames.length == 0) { - hl.linkStats.countEmptyDirs++; + String[] blockNames = from.list(new java.io.FilenameFilter() { + public boolean accept(File dir, String name) { + return name.startsWith(BLOCK_FILE_PREFIX); } - else for(int i = 0; i < blockNames.length; i++) - linkBlocks(new File(from, blockNames[i]), - new File(to, blockNames[i]), oldLV, hl); - } - else { - //If upgrading from a relatively new version, we only need to create - //links with the same filename. This can be done in bulk (much faster). - String[] blockNames = from.list(new java.io.FilenameFilter() { + }); + + // Block files just need hard links with the same file names + // but a different directory + if (blockNames.length > 0) { + HardLink.createHardLinkMult(from, blockNames, to); + hl.linkStats.countMultLinks++; + hl.linkStats.countFilesMultLinks += blockNames.length; + } else { + hl.linkStats.countEmptyDirs++; + } + + // Now take care of the rest of the files and subdirectories + String[] otherNames = from.list(new java.io.FilenameFilter() { public boolean accept(File dir, String name) { - return name.startsWith(BLOCK_FILE_PREFIX); + return name.startsWith(BLOCK_SUBDIR_PREFIX) + || name.startsWith(COPY_FILE_PREFIX); } }); - if (blockNames.length > 0) { - HardLink.createHardLinkMult(from, blockNames, to); - hl.linkStats.countMultLinks++; - hl.linkStats.countFilesMultLinks += blockNames.length; - } else { - hl.linkStats.countEmptyDirs++; - } - - //now take care of the rest of the files and subdirectories - String[] otherNames = from.list(new java.io.FilenameFilter() { - public boolean accept(File dir, String name) { - return name.startsWith(BLOCK_SUBDIR_PREFIX) - || name.startsWith(COPY_FILE_PREFIX); - } - }); - for(int i = 0; i < otherNames.length; i++) - linkBlocks(new File(from, otherNames[i]), - new File(to, otherNames[i]), oldLV, hl); - } + for(int i = 0; i < otherNames.length; i++) + linkBlocks(new File(from, otherNames[i]), + new File(to, otherNames[i]), oldLV, hl); } private void verifyDistributedUpgradeProgress(UpgradeManagerDatanode um, @@ -741,22 +713,6 @@ public class DataStorage extends Storage { um.initializeUpgrade(nsInfo); } - /** - * This is invoked on target file names when upgrading from pre generation - * stamp version (version -13) to correct the metatadata file name. - * @param oldFileName - * @return the new metadata file name with the default generation stamp. - */ - private static String convertMetatadataFileName(String oldFileName) { - Matcher matcher = PRE_GENSTAMP_META_FILE_PATTERN.matcher(oldFileName); - if (matcher.matches()) { - //return the current metadata file name - return DatanodeUtil.getMetaFileName(matcher.group(1), - GenerationStamp.GRANDFATHER_GENERATION_STAMP); - } - return oldFileName; - } - /** * Add bpStorage into bpStorageMap */ diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java index 75722d458e7..0edf55d6bdf 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogLoader.java @@ -64,7 +64,6 @@ import org.apache.hadoop.hdfs.server.namenode.FSEditLogOp.UpdateBlocksOp; import org.apache.hadoop.hdfs.server.namenode.FSEditLogOp.UpdateMasterKeyOp; import org.apache.hadoop.hdfs.server.namenode.LeaseManager.Lease; import org.apache.hadoop.hdfs.util.Holder; -import org.apache.hadoop.io.IOUtils; import com.google.common.base.Joiner; @@ -233,37 +232,13 @@ public class FSEditLogLoader { // get name and replication final short replication = fsNamesys.getBlockManager( ).adjustReplication(addCloseOp.replication); - PermissionStatus permissions = fsNamesys.getUpgradePermission(); - if (addCloseOp.permissions != null) { - permissions = addCloseOp.permissions; - } - long blockSize = addCloseOp.blockSize; - - // Versions of HDFS prior to 0.17 may log an OP_ADD transaction - // which includes blocks in it. When we update the minimum - // upgrade version to something more recent than 0.17, we can - // simplify this code by asserting that OP_ADD transactions - // don't have any blocks. - - // Older versions of HDFS does not store the block size in inode. - // If the file has more than one block, use the size of the - // first block as the blocksize. Otherwise use the default - // block size. - if (-8 <= logVersion && blockSize == 0) { - if (addCloseOp.blocks.length > 1) { - blockSize = addCloseOp.blocks[0].getNumBytes(); - } else { - long first = ((addCloseOp.blocks.length == 1)? - addCloseOp.blocks[0].getNumBytes(): 0); - blockSize = Math.max(fsNamesys.getDefaultBlockSize(), first); - } - } + assert addCloseOp.blocks.length == 0; // add to the file tree newFile = (INodeFile)fsDir.unprotectedAddFile( - addCloseOp.path, permissions, + addCloseOp.path, addCloseOp.permissions, replication, addCloseOp.mtime, - addCloseOp.atime, blockSize, + addCloseOp.atime, addCloseOp.blockSize, true, addCloseOp.clientName, addCloseOp.clientMachine); fsNamesys.leaseManager.addLease(addCloseOp.clientName, addCloseOp.path); @@ -375,12 +350,7 @@ public class FSEditLogLoader { } case OP_MKDIR: { MkdirOp mkdirOp = (MkdirOp)op; - PermissionStatus permissions = fsNamesys.getUpgradePermission(); - if (mkdirOp.permissions != null) { - permissions = mkdirOp.permissions; - } - - fsDir.unprotectedMkdir(mkdirOp.path, permissions, + fsDir.unprotectedMkdir(mkdirOp.path, mkdirOp.permissions, mkdirOp.timestamp); break; } @@ -495,9 +465,6 @@ public class FSEditLogLoader { // no data in here currently. break; } - case OP_DATANODE_ADD: - case OP_DATANODE_REMOVE: - break; default: throw new IOException("Invalid operation read " + op.opCode); } diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOp.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOp.java index 949554dbda0..3c9dab4b0ec 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOp.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOp.java @@ -30,11 +30,8 @@ import org.apache.hadoop.fs.Options.Rename; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.fs.permission.PermissionStatus; import org.apache.hadoop.hdfs.protocol.Block; -import org.apache.hadoop.hdfs.protocol.DatanodeID; import org.apache.hadoop.hdfs.protocol.LayoutVersion; import org.apache.hadoop.hdfs.protocol.LayoutVersion.Feature; -import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor; -import org.apache.hadoop.hdfs.server.common.GenerationStamp; import org.apache.hadoop.util.PureJavaCrc32; import static org.apache.hadoop.hdfs.server.namenode.FSEditLogOpCodes.*; @@ -81,8 +78,6 @@ public abstract class FSEditLogOp { instances.put(OP_DELETE, new DeleteOp()); instances.put(OP_MKDIR, new MkdirOp()); instances.put(OP_SET_GENSTAMP, new SetGenstampOp()); - instances.put(OP_DATANODE_ADD, new DatanodeAddOp()); - instances.put(OP_DATANODE_REMOVE, new DatanodeRemoveOp()); instances.put(OP_SET_PERMISSIONS, new SetPermissionsOp()); instances.put(OP_SET_OWNER, new SetOwnerOp()); instances.put(OP_SET_NS_QUOTA, new SetNSQuotaOp()); @@ -147,7 +142,6 @@ public abstract class FSEditLogOp { PermissionStatus permissions; String clientName; String clientMachine; - //final DatanodeDescriptor[] dataNodeDescriptors; UNUSED private AddCloseOp(FSEditLogOpCodes opCode) { super(opCode); @@ -226,13 +220,10 @@ public abstract class FSEditLogOp { @Override void readFields(DataInputStream in, int logVersion) throws IOException { - // versions > 0 support per file replication - // get name and replication if (!LayoutVersion.supports(Feature.EDITLOG_OP_OPTIMIZATION, logVersion)) { this.length = in.readInt(); } - if (-7 == logVersion && length != 3|| - -17 < logVersion && logVersion < -7 && length != 4 || + if ((-17 < logVersion && length != 4) || (logVersion <= -17 && length != 5 && !LayoutVersion.supports( Feature.EDITLOG_OP_OPTIMIZATION, logVersion))) { throw new IOException("Incorrect data format." + @@ -259,49 +250,26 @@ public abstract class FSEditLogOp { } else { this.atime = 0; } - if (logVersion < -7) { - if (LayoutVersion.supports(Feature.EDITLOG_OP_OPTIMIZATION, logVersion)) { - this.blockSize = FSImageSerialization.readLong(in); - } else { - this.blockSize = readLong(in); - } + + if (LayoutVersion.supports(Feature.EDITLOG_OP_OPTIMIZATION, logVersion)) { + this.blockSize = FSImageSerialization.readLong(in); } else { - this.blockSize = 0; + this.blockSize = readLong(in); } - // get blocks this.blocks = readBlocks(in, logVersion); - - if (logVersion <= -11) { - this.permissions = PermissionStatus.read(in); - } else { - this.permissions = null; - } + this.permissions = PermissionStatus.read(in); // clientname, clientMachine and block locations of last block. - if (this.opCode == OP_ADD && logVersion <= -12) { + if (this.opCode == OP_ADD) { this.clientName = FSImageSerialization.readString(in); this.clientMachine = FSImageSerialization.readString(in); - if (-13 <= logVersion) { - readDatanodeDescriptorArray(in); - } } else { this.clientName = ""; this.clientMachine = ""; } } - /** This method is defined for compatibility reason. */ - private static DatanodeDescriptor[] readDatanodeDescriptorArray(DataInput in) - throws IOException { - DatanodeDescriptor[] locations = new DatanodeDescriptor[in.readInt()]; - for (int i = 0; i < locations.length; i++) { - locations[i] = new DatanodeDescriptor(); - locations[i].readFieldsFromFSEditLog(in); - } - return locations; - } - private static Block[] readBlocks( DataInputStream in, int logVersion) throws IOException { @@ -309,14 +277,7 @@ public abstract class FSEditLogOp { Block[] blocks = new Block[numBlocks]; for (int i = 0; i < numBlocks; i++) { Block blk = new Block(); - if (logVersion <= -14) { - blk.readFields(in); - } else { - BlockTwo oldblk = new BlockTwo(); - oldblk.readFields(in); - blk.set(oldblk.blkid, oldblk.len, - GenerationStamp.GRANDFATHER_GENERATION_STAMP); - } + blk.readFields(in); blocks[i] = blk; } return blocks; @@ -788,17 +749,14 @@ public abstract class FSEditLogOp { } @Override - void readFields(DataInputStream in, int logVersion) - throws IOException { - + void readFields(DataInputStream in, int logVersion) throws IOException { if (!LayoutVersion.supports(Feature.EDITLOG_OP_OPTIMIZATION, logVersion)) { this.length = in.readInt(); } if (-17 < logVersion && length != 2 || logVersion <= -17 && length != 3 && !LayoutVersion.supports(Feature.EDITLOG_OP_OPTIMIZATION, logVersion)) { - throw new IOException("Incorrect data format. " - + "Mkdir operation."); + throw new IOException("Incorrect data format. Mkdir operation."); } this.path = FSImageSerialization.readString(in); if (LayoutVersion.supports(Feature.EDITLOG_OP_OPTIMIZATION, logVersion)) { @@ -811,7 +769,6 @@ public abstract class FSEditLogOp { // However, currently this is not being updated/used because of // performance reasons. if (LayoutVersion.supports(Feature.FILE_ACCESS_TIME, logVersion)) { - /* unused this.atime = */ if (LayoutVersion.supports(Feature.EDITLOG_OP_OPTIMIZATION, logVersion)) { FSImageSerialization.readLong(in); } else { @@ -819,11 +776,7 @@ public abstract class FSEditLogOp { } } - if (logVersion <= -11) { - this.permissions = PermissionStatus.read(in); - } else { - this.permissions = null; - } + this.permissions = PermissionStatus.read(in); } @Override @@ -888,77 +841,6 @@ public abstract class FSEditLogOp { } } - @SuppressWarnings("deprecation") - static class DatanodeAddOp extends FSEditLogOp { - private DatanodeAddOp() { - super(OP_DATANODE_ADD); - } - - static DatanodeAddOp getInstance() { - return (DatanodeAddOp)opInstances.get() - .get(OP_DATANODE_ADD); - } - - @Override - void writeFields(DataOutputStream out) throws IOException { - throw new IOException("Deprecated, should not write"); - } - - @Override - void readFields(DataInputStream in, int logVersion) - throws IOException { - //Datanodes are not persistent any more. - FSImageSerialization.DatanodeImage.skipOne(in); - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("DatanodeAddOp [opCode="); - builder.append(opCode); - builder.append(", txid="); - builder.append(txid); - builder.append("]"); - return builder.toString(); - } - } - - @SuppressWarnings("deprecation") - static class DatanodeRemoveOp extends FSEditLogOp { - private DatanodeRemoveOp() { - super(OP_DATANODE_REMOVE); - } - - static DatanodeRemoveOp getInstance() { - return (DatanodeRemoveOp)opInstances.get() - .get(OP_DATANODE_REMOVE); - } - - @Override - void writeFields(DataOutputStream out) throws IOException { - throw new IOException("Deprecated, should not write"); - } - - @Override - void readFields(DataInputStream in, int logVersion) - throws IOException { - DatanodeID nodeID = new DatanodeID(); - nodeID.readFields(in); - //Datanodes are not persistent any more. - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("DatanodeRemoveOp [opCode="); - builder.append(opCode); - builder.append(", txid="); - builder.append(txid); - builder.append("]"); - return builder.toString(); - } - } - static class SetPermissionsOp extends FSEditLogOp { String src; FsPermission permissions; diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOpCodes.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOpCodes.java index 1f809c12b26..c08a5a92a92 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOpCodes.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSEditLogOpCodes.java @@ -36,8 +36,8 @@ public enum FSEditLogOpCodes { OP_DELETE ((byte) 2), OP_MKDIR ((byte) 3), OP_SET_REPLICATION ((byte) 4), - @Deprecated OP_DATANODE_ADD ((byte) 5), - @Deprecated OP_DATANODE_REMOVE((byte) 6), + @Deprecated OP_DATANODE_ADD ((byte) 5), // obsolete + @Deprecated OP_DATANODE_REMOVE((byte) 6), // obsolete OP_SET_PERMISSIONS ((byte) 7), OP_SET_OWNER ((byte) 8), OP_CLOSE ((byte) 9), diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageFormat.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageFormat.java index e029b240229..f666f35b749 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageFormat.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageFormat.java @@ -131,34 +131,22 @@ class FSImageFormat { DataInputStream in = new DataInputStream(fin); try { - /* - * Note: Remove any checks for version earlier than - * Storage.LAST_UPGRADABLE_LAYOUT_VERSION since we should never get - * to here with older images. - */ - - /* - * TODO we need to change format of the image file - * it should not contain version and namespace fields - */ // read image version: first appeared in version -1 int imgVersion = in.readInt(); - if(getLayoutVersion() != imgVersion) + if (getLayoutVersion() != imgVersion) { throw new InconsistentFSStateException(curFile, "imgVersion " + imgVersion + " expected to be " + getLayoutVersion()); + } // read namespaceID: first appeared in version -2 in.readInt(); - // read number of files - long numFiles = readNumFiles(in); + long numFiles = in.readLong(); // read in the last generation stamp. - if (imgVersion <= -12) { - long genstamp = in.readLong(); - namesystem.setGenerationStamp(genstamp); - } + long genstamp = in.readLong(); + namesystem.setGenerationStamp(genstamp); // read the transaction ID of the last edit represented by // this image @@ -167,7 +155,6 @@ class FSImageFormat { } else { imgTxId = 0; } - // read compression related info FSImageCompression compression; @@ -189,13 +176,9 @@ class FSImageFormat { loadFullNameINodes(numFiles, in); } - // load datanode info - this.loadDatanodes(in); + loadFilesUnderConstruction(in); - // load Files Under Construction - this.loadFilesUnderConstruction(in); - - this.loadSecretManagerState(in); + loadSecretManagerState(in); // make sure to read to the end of file int eof = in.read(); @@ -335,89 +318,44 @@ class FSImageFormat { if (LayoutVersion.supports(Feature.FILE_ACCESS_TIME, imgVersion)) { atime = in.readLong(); } - if (imgVersion <= -8) { - blockSize = in.readLong(); - } + blockSize = in.readLong(); int numBlocks = in.readInt(); BlockInfo blocks[] = null; - // for older versions, a blocklist of size 0 - // indicates a directory. - if ((-9 <= imgVersion && numBlocks > 0) || - (imgVersion < -9 && numBlocks >= 0)) { + if (numBlocks >= 0) { blocks = new BlockInfo[numBlocks]; for (int j = 0; j < numBlocks; j++) { blocks[j] = new BlockInfo(replication); - if (-14 < imgVersion) { - blocks[j].set(in.readLong(), in.readLong(), - GenerationStamp.GRANDFATHER_GENERATION_STAMP); - } else { - blocks[j].readFields(in); - } - } - } - // Older versions of HDFS does not store the block size in inode. - // If the file has more than one block, use the size of the - // first block as the blocksize. Otherwise use the default block size. - // - if (-8 <= imgVersion && blockSize == 0) { - if (numBlocks > 1) { - blockSize = blocks[0].getNumBytes(); - } else { - long first = ((numBlocks == 1) ? blocks[0].getNumBytes(): 0); - blockSize = Math.max(namesystem.getDefaultBlockSize(), first); + blocks[j].readFields(in); } } // get quota only when the node is a directory long nsQuota = -1L; - if (LayoutVersion.supports(Feature.NAMESPACE_QUOTA, imgVersion) - && blocks == null && numBlocks == -1) { - nsQuota = in.readLong(); - } - long dsQuota = -1L; - if (LayoutVersion.supports(Feature.DISKSPACE_QUOTA, imgVersion) - && blocks == null && numBlocks == -1) { - dsQuota = in.readLong(); - } - - // Read the symlink only when the node is a symlink - String symlink = ""; - if (numBlocks == -2) { - symlink = Text.readString(in); - } - - PermissionStatus permissions = namesystem.getUpgradePermission(); - if (imgVersion <= -11) { - permissions = PermissionStatus.read(in); - } - - return INode.newINode(permissions, blocks, symlink, replication, - modificationTime, atime, nsQuota, dsQuota, blockSize); + if (blocks == null && numBlocks == -1) { + nsQuota = in.readLong(); + } + long dsQuota = -1L; + if (LayoutVersion.supports(Feature.DISKSPACE_QUOTA, imgVersion) + && blocks == null && numBlocks == -1) { + dsQuota = in.readLong(); } - private void loadDatanodes(DataInputStream in) - throws IOException { - int imgVersion = getLayoutVersion(); - - if (imgVersion > -3) // pre datanode image version - return; - if (imgVersion <= -12) { - return; // new versions do not store the datanodes any more. - } - int size = in.readInt(); - for(int i = 0; i < size; i++) { - // We don't need to add these descriptors any more. - FSImageSerialization.DatanodeImage.skipOne(in); - } + // Read the symlink only when the node is a symlink + String symlink = ""; + if (numBlocks == -2) { + symlink = Text.readString(in); } + + PermissionStatus permissions = PermissionStatus.read(in); + + return INode.newINode(permissions, blocks, symlink, replication, + modificationTime, atime, nsQuota, dsQuota, blockSize); + } private void loadFilesUnderConstruction(DataInputStream in) throws IOException { FSDirectory fsDir = namesystem.dir; - int imgVersion = getLayoutVersion(); - if (imgVersion > -13) // pre lease image version - return; int size = in.readInt(); LOG.info("Number of files under construction = " + size); @@ -457,17 +395,6 @@ class FSImageFormat { return namesystem.getFSImage().getStorage().getLayoutVersion(); } - private long readNumFiles(DataInputStream in) - throws IOException { - int imgVersion = getLayoutVersion(); - - if (LayoutVersion.supports(Feature.NAMESPACE_QUOTA, imgVersion)) { - return in.readLong(); - } else { - return in.readInt(); - } - } - private boolean isRoot(byte[][] path) { return path.length == 1 && path[0] == null; diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageSerialization.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageSerialization.java index f5084339e8d..d6453fa8b54 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageSerialization.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSImageSerialization.java @@ -17,9 +17,7 @@ */ package org.apache.hadoop.hdfs.server.namenode; -import java.io.DataInput; import java.io.DataInputStream; -import java.io.DataOutput; import java.io.DataOutputStream; import java.io.IOException; @@ -31,7 +29,6 @@ import org.apache.hadoop.fs.permission.PermissionStatus; import org.apache.hadoop.hdfs.DFSUtil; import org.apache.hadoop.hdfs.DeprecatedUTF8; import org.apache.hadoop.hdfs.protocol.Block; -import org.apache.hadoop.hdfs.protocol.DatanodeID; import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo; import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfoUnderConstruction; import org.apache.hadoop.hdfs.server.blockmanagement.DatanodeDescriptor; @@ -39,7 +36,6 @@ import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.BlockUCState; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.ShortWritable; import org.apache.hadoop.io.Text; -import org.apache.hadoop.io.Writable; import org.apache.hadoop.io.WritableUtils; /** @@ -107,13 +103,10 @@ public class FSImageSerialization { String clientName = readString(in); String clientMachine = readString(in); - // These locations are not used at all + // We previously stored locations for the last block, now we + // just record that there are none int numLocs = in.readInt(); - DatanodeDescriptor[] locations = new DatanodeDescriptor[numLocs]; - for (i = 0; i < numLocs; i++) { - locations[i] = new DatanodeDescriptor(); - locations[i].readFields(in); - } + assert numLocs == 0 : "Unexpected block locations"; return new INodeFileUnderConstruction(name, blockReplication, @@ -320,53 +313,4 @@ public class FSImageSerialization { } return ret; } - - /** - * DatanodeImage is used to store persistent information - * about datanodes into the fsImage. - */ - static class DatanodeImage implements Writable { - DatanodeDescriptor node = new DatanodeDescriptor(); - - static void skipOne(DataInput in) throws IOException { - DatanodeImage nodeImage = new DatanodeImage(); - nodeImage.readFields(in); - } - - ///////////////////////////////////////////////// - // Writable - ///////////////////////////////////////////////// - /** - * Public method that serializes the information about a - * Datanode to be stored in the fsImage. - */ - public void write(DataOutput out) throws IOException { - new DatanodeID(node).write(out); - out.writeLong(node.getCapacity()); - out.writeLong(node.getRemaining()); - out.writeLong(node.getLastUpdate()); - out.writeInt(node.getXceiverCount()); - } - - /** - * Public method that reads a serialized Datanode - * from the fsImage. - */ - public void readFields(DataInput in) throws IOException { - DatanodeID id = new DatanodeID(); - id.readFields(in); - long capacity = in.readLong(); - long remaining = in.readLong(); - long lastUpdate = in.readLong(); - int xceiverCount = in.readInt(); - - // update the DatanodeDescriptor with the data we read in - node.updateRegInfo(id); - node.setStorageID(id.getStorageID()); - node.setCapacity(capacity); - node.setRemaining(remaining); - node.setLastUpdate(lastUpdate); - node.setXceiverCount(xceiverCount); - } - } } \ No newline at end of file diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java index ae910daaebc..91e1dbac188 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java @@ -877,14 +877,6 @@ public class FSNamesystem implements Namesystem, FSClusterStats, DFS_NAMENODE_DELEGATION_TOKEN_ALWAYS_USE_DEFAULT); } - /** - * Return the default path permission when upgrading from releases with no - * permissions (<=0.15) to releases with permissions (>=0.16) - */ - protected PermissionStatus getUpgradePermission() { - return defaultPermission; - } - NamespaceInfo getNamespaceInfo() { readLock(); try { diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSUpgradeFromImage.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSUpgradeFromImage.java index 567fbabdddb..ba92c569d95 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSUpgradeFromImage.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSUpgradeFromImage.java @@ -52,7 +52,6 @@ public class TestDFSUpgradeFromImage extends TestCase { .getLog(TestDFSUpgradeFromImage.class); private static File TEST_ROOT_DIR = new File(MiniDFSCluster.getBaseDirectory()); - private static final String HADOOP14_IMAGE = "hadoop-14-dfs-dir.tgz"; private static final String HADOOP_DFS_DIR_TXT = "hadoop-dfs-dir.txt"; private static final String HADOOP22_IMAGE = "hadoop-22-dfs-dir.tgz"; @@ -68,10 +67,6 @@ public class TestDFSUpgradeFromImage extends TestCase { boolean printChecksum = false; - public void unpackStorage() throws IOException { - unpackStorage(HADOOP14_IMAGE); - } - private void unpackStorage(String tarFileName) throws IOException { String tarFile = System.getProperty("test.cache.data", "build/test/cache") @@ -227,14 +222,6 @@ public class TestDFSUpgradeFromImage extends TestCase { } } - /** - * Test upgrade from an 0.14 image - */ - public void testUpgradeFromRel14Image() throws IOException { - unpackStorage(); - upgradeAndVerify(); - } - /** * Test upgrade from 0.22 image */ diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/common/TestDistributedUpgrade.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/common/TestDistributedUpgrade.java deleted file mode 100644 index 25dce520a68..00000000000 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/common/TestDistributedUpgrade.java +++ /dev/null @@ -1,267 +0,0 @@ -/** -* 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.hdfs.server.common; - -import static org.apache.hadoop.hdfs.protocol.HdfsConstants.LAYOUT_VERSION; - -import java.io.IOException; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hdfs.DFSConfigKeys; -import org.apache.hadoop.hdfs.HdfsConfiguration; -import org.apache.hadoop.hdfs.MiniDFSCluster; -import org.apache.hadoop.hdfs.TestDFSUpgradeFromImage; -import org.apache.hadoop.hdfs.server.common.HdfsServerConstants.StartupOption; -import org.apache.hadoop.hdfs.server.datanode.UpgradeObjectDatanode; -import org.apache.hadoop.hdfs.server.namenode.UpgradeObjectNamenode; -import org.apache.hadoop.hdfs.server.protocol.DatanodeProtocol; -import org.apache.hadoop.hdfs.server.protocol.UpgradeCommand; -import org.apache.hadoop.hdfs.tools.DFSAdmin; -import org.apache.hadoop.test.GenericTestUtils; - -import org.junit.Test; -import static org.junit.Assert.*; - -/** - */ -public class TestDistributedUpgrade { - private static final Log LOG = LogFactory.getLog(TestDistributedUpgrade.class); - private Configuration conf; - private int testCounter = 0; - private MiniDFSCluster cluster = null; - private String clusterId = "testClsterId"; - - /** - * Writes an INFO log message containing the parameters. - */ - void log(String label, int numDirs) { - LOG.info("============================================================"); - LOG.info("***TEST " + (testCounter++) + "*** " - + label + ":" - + " numDirs="+numDirs); - } - - /** - * Attempts to start a NameNode with the given operation. Starting - * the NameNode should throw an exception. - */ - void startNameNodeShouldFail(StartupOption operation, - String exceptionSubstring) { - try { - //cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).startupOption(operation).build(); // should fail - // we set manage dirs to true as NN has to start from untar'ed image with - // nn dirs set to name1 and name2 - cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0) - .format(false) - .clusterId(clusterId) - .startupOption(operation) - .build(); // should fail - throw new AssertionError("NameNode should have failed to start"); - } catch (Exception expected) { - GenericTestUtils.assertExceptionContains( - exceptionSubstring, expected); - } - } - - /** - * Attempts to start a DataNode with the given operation. Starting - * the DataNode should throw an exception. - */ - void startDataNodeShouldFail(StartupOption operation) { - try { - cluster.startDataNodes(conf, 1, false, operation, null); // should fail - throw new AssertionError("DataNode should have failed to start"); - } catch (Exception expected) { - // expected - assertFalse(cluster.isDataNodeUp()); - } - } - - /** - */ - @Test(timeout=300000) // 5 min timeout - public void testDistributedUpgrade() throws Exception { - int numDirs = 1; - TestDFSUpgradeFromImage testImg = new TestDFSUpgradeFromImage(); - testImg.unpackStorage(); - int numDNs = testImg.numDataNodes; - - // register new upgrade objects (ignore all existing) - UpgradeObjectCollection.initialize(); - UpgradeObjectCollection.registerUpgrade(new UO_Datanode1()); - UpgradeObjectCollection.registerUpgrade(new UO_Namenode1()); - UpgradeObjectCollection.registerUpgrade(new UO_Datanode2()); - UpgradeObjectCollection.registerUpgrade(new UO_Namenode2()); - UpgradeObjectCollection.registerUpgrade(new UO_Datanode3()); - UpgradeObjectCollection.registerUpgrade(new UO_Namenode3()); - - conf = new HdfsConfiguration(); - if (System.getProperty("test.build.data") == null) { // to test to be run outside of ant - System.setProperty("test.build.data", "build/test/data"); - } - conf.setInt(DFSConfigKeys.DFS_DATANODE_SCAN_PERIOD_HOURS_KEY, -1); // block scanning off - - log("NameNode start in regular mode when dustributed upgrade is required", numDirs); - startNameNodeShouldFail(StartupOption.REGULAR, "contains an old layout version"); - - log("Start NameNode only distributed upgrade", numDirs); - // cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0).format(false) - // .startupOption(StartupOption.UPGRADE).build(); - cluster = new MiniDFSCluster.Builder(conf).numDataNodes(0) - .format(false) - .clusterId(clusterId) - .startupOption(StartupOption.UPGRADE) - .build(); - cluster.shutdown(); - - log("NameNode start in regular mode when dustributed upgrade has been started", numDirs); - startNameNodeShouldFail(StartupOption.REGULAR, - "Previous distributed upgrade was not completed"); - - log("NameNode rollback to the old version that require a dustributed upgrade", numDirs); - startNameNodeShouldFail(StartupOption.ROLLBACK, - "Cannot rollback to storage version -7 using this version"); - - log("Normal distributed upgrade for the cluster", numDirs); - cluster = new MiniDFSCluster.Builder(conf) - .numDataNodes(numDNs) - .format(false) - .clusterId(clusterId) - .startupOption(StartupOption.UPGRADE) - .build(); - DFSAdmin dfsAdmin = new DFSAdmin(); - dfsAdmin.setConf(conf); - dfsAdmin.run(new String[] {"-safemode", "wait"}); - cluster.shutdown(); - - // it should be ok to start in regular mode - log("NameCluster regular startup after the upgrade", numDirs); - cluster = new MiniDFSCluster.Builder(conf) - .numDataNodes(numDNs) - .clusterId(clusterId) - .format(false) - .startupOption(StartupOption.REGULAR) - .build(); - - cluster.waitActive(); - cluster.shutdown(); - } - - public static void main(String[] args) throws Exception { - new TestDistributedUpgrade().testDistributedUpgrade(); - LOG.info("=== DONE ==="); - } -} - -/** - * Upgrade object for data-node - */ -class UO_Datanode extends UpgradeObjectDatanode { - int version; - - UO_Datanode(int v) { - this.status = (short)0; - version = v; - } - - public int getVersion() { - return version; - } - - public void doUpgrade() throws IOException { - this.status = (short)100; - DatanodeProtocol nn = getNamenode(); - nn.processUpgradeCommand( - new UpgradeCommand(UpgradeCommand.UC_ACTION_REPORT_STATUS, - getVersion(), getUpgradeStatus())); - } - - public UpgradeCommand startUpgrade() throws IOException { - return null; - } -} - -/** - * Upgrade object for name-node - */ -class UO_Namenode extends UpgradeObjectNamenode { - int version; - - UO_Namenode(int v) { - status = (short)0; - version = v; - } - - public int getVersion() { - return version; - } - - synchronized public UpgradeCommand processUpgradeCommand( - UpgradeCommand command) throws IOException { - switch(command.getAction()) { - case UpgradeCommand.UC_ACTION_REPORT_STATUS: - this.status += command.getCurrentStatus()/8; // 4 reports needed - break; - default: - this.status++; - } - return null; - } - - public UpgradeCommand completeUpgrade() throws IOException { - return null; - } -} - -class UO_Datanode1 extends UO_Datanode { - UO_Datanode1() { - super(LAYOUT_VERSION+1); - } -} - -class UO_Namenode1 extends UO_Namenode { - UO_Namenode1() { - super(LAYOUT_VERSION+1); - } -} - -class UO_Datanode2 extends UO_Datanode { - UO_Datanode2() { - super(LAYOUT_VERSION+2); - } -} - -class UO_Namenode2 extends UO_Namenode { - UO_Namenode2() { - super(LAYOUT_VERSION+2); - } -} - -class UO_Datanode3 extends UO_Datanode { - UO_Datanode3() { - super(LAYOUT_VERSION+3); - } -} - -class UO_Namenode3 extends UO_Namenode { - UO_Namenode3() { - super(LAYOUT_VERSION+3); - } -} diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/TestOfflineEditsViewer.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/TestOfflineEditsViewer.java index 9ebc13e5ed1..36b22206410 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/TestOfflineEditsViewer.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/tools/offlineEditsViewer/TestOfflineEditsViewer.java @@ -65,12 +65,11 @@ public class TestOfflineEditsViewer { * * These are the opcodes that are not used anymore, some * are marked deprecated, we need to include them here to make - * sure we exclude them when checking for completness of testing, + * sure we exclude them when checking for completeness of testing, * that's why the "deprecation" warnings are suppressed. */ @SuppressWarnings("deprecation") private static void initializeObsoleteOpCodes() { - // these are obsolete obsoleteOpCodes.put(FSEditLogOpCodes.OP_DATANODE_ADD, true); obsoleteOpCodes.put(FSEditLogOpCodes.OP_DATANODE_REMOVE, true); obsoleteOpCodes.put(FSEditLogOpCodes.OP_SET_NS_QUOTA, true); diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/hadoop-14-dfs-dir.tgz b/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/hadoop-14-dfs-dir.tgz deleted file mode 100644 index 4d571a595190b90158f318ebc8e8b8dab1d180da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153081 zcmeFa30zZWx<5Ym_ReVQg4P8WB;$$;LS;vmv{FR`M8$w8kP5O35s)2nX6k|)L`6Ud zkU<25u*e$rv?3q`h_Xf26aoYY5FsQX+j)Pn+Foo0=FZIje|tMQA3uQkB=0%zvwWZJ zeV!n0Fa1Nc&HAH%_+-3y*h0Y&@yjzEC2a_A`Z_5FOS5I7hat|@S*uLLS3qBRMrl6mc|_ktL(oMk)D+2T^;9=a9KD?#Uz9d>oOBUI%+K~+-8P1OR}@EjxLhu zhl%W&jwXzkeoA{1f&S|CtHeaMmXH$>7j~_j8gM%LXA3PA`I7=nXwim90>8bJ0ZmO=%58}ZP|%c6 zwflq}2)ZHm%bAk;Fm|m<`K4J$*pQXz+exxV_6(xgq1B=)@#Z!34UypKYy*VldLqc~ zI@s@?tAc7xY9i822kw1y!_-0~^ljb}34XvroZ$jUbR~Rw9mo?rrAqoCs@&#C1ourX zUlEiARC(yY5|Kb_ZK!nsNoT9^@EU%twriH?3eEkXea3w}Mc2wO(EKIM0ct+P5e90> L$CynlJ! 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 MXuSQ-xy*n0AD{{+6aWAK diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/hadoop-dfs-dir.txt b/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/hadoop-dfs-dir.txt index 3d1b67dae31..0fbc3189aad 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/hadoop-dfs-dir.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/resources/hadoop-dfs-dir.txt @@ -19,18 +19,6 @@ # See HADOOP-1629 for more info if needed. # These two files are used by unit test TestDFSUpgradeFromImage.java # -# hadoop-14-dfs-dir.tgz : -# --------------------- -# This file contains the HDFS directory structure for one namenode and 4 datanodes. -# The structure is setup similar to the structure used in MiniDFSCluster. -# The directory was created with Hadoo-0.14.x. -# -# In the test, this directory is unpacked and MiniDFSCluster is run with -# "-upgrade" option. The test waits for the upgrade to complete -# (leave safe mode) and then all the files are read. The test checks that the -# directory structure and file checksums exactly match the information -# in this file. -# # hadoop-dfs-dir.txt : # --------------------- # Along with this description this file contains the expected files and @@ -43,9 +31,6 @@ # For e.g. "top-dir-1Mb-512" contains files created with dfs.blocksize of 1Mb # and io.bytes.per.checksum of 512. # -# In the future, when Hadoop project no longer supports upgrade from -# Hadoop-0.12, then a new DFS directory image must be created. -# # To generate checksum info for new files : # --------------------------------------- # Uncomment the last coment (starts with "printChecksums") and run the