HDFS-6563. NameNode cannot save fsimage in certain circumstances when snapshots are in use. Contributed by Aaron T. Myers.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/trunk@1603712 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Aaron Myers 2014-06-19 05:17:58 +00:00
parent a4e0ff5e05
commit 3f82484218
4 changed files with 45 additions and 3 deletions

View File

@ -670,6 +670,9 @@ Release 2.5.0 - UNRELEASED
HDFS-6553. Add missing DeprecationDeltas for NFS Kerberos configurations
(Stephen Chu via brandonli)
HDFS-6563. NameNode cannot save fsimage in certain circumstances when
snapshots are in use. (atm)
BREAKDOWN OF HDFS-2006 SUBTASKS AND RELATED JIRAS
HDFS-6299. Protobuf for XAttr and client-side implementation. (Yi Liu via umamahesh)

View File

@ -533,8 +533,10 @@ public final class FSImageFormatPBINode {
INodeSection.INodeFile.Builder b = buildINodeFile(n,
parent.getSaverContext());
for (Block block : n.getBlocks()) {
b.addBlocks(PBHelper.convert(block));
if (n.getBlocks() != null) {
for (Block block : n.getBlocks()) {
b.addBlocks(PBHelper.convert(block));
}
}
FileUnderConstructionFeature uc = n.getFileUnderConstructionFeature();

View File

@ -159,7 +159,7 @@ public class FileWithSnapshotFeature implements INode.Feature {
// resize the array.
final BlockInfo[] newBlocks;
if (n == 0) {
newBlocks = null;
newBlocks = BlockInfo.EMPTY_ARRAY;
} else {
newBlocks = new BlockInfo[n];
System.arraycopy(oldBlocks, 0, newBlocks, 0, n);

View File

@ -28,12 +28,14 @@ import static org.junit.Assert.fail;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.DFSConfigKeys;
import org.apache.hadoop.hdfs.DFSTestUtil;
import org.apache.hadoop.hdfs.DistributedFileSystem;
import org.apache.hadoop.hdfs.MiniDFSCluster;
import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
import org.apache.hadoop.hdfs.protocol.HdfsConstants.SafeModeAction;
import org.apache.hadoop.hdfs.server.blockmanagement.BlockInfo;
import org.apache.hadoop.hdfs.server.blockmanagement.BlockManager;
import org.apache.hadoop.hdfs.server.namenode.FSDirectory;
@ -396,4 +398,39 @@ public class TestSnapshotBlocksMap {
assertEquals(1, blks.length);
assertEquals(BLOCKSIZE, blks[0].getNumBytes());
}
/**
* Make sure that a delete of a non-zero-length file which results in a
* zero-length file in a snapshot works.
*/
@Test
public void testDeletionOfLaterBlocksWithZeroSizeFirstBlock() throws Exception {
final Path foo = new Path("/foo");
final Path bar = new Path(foo, "bar");
final byte[] testData = "foo bar baz".getBytes();
// Create a zero-length file.
DFSTestUtil.createFile(hdfs, bar, 0, REPLICATION, 0L);
assertEquals(0, fsdir.getINode4Write(bar.toString()).asFile().getBlocks().length);
// Create a snapshot that includes that file.
SnapshotTestHelper.createSnapshot(hdfs, foo, "s0");
// Extend that file.
FSDataOutputStream out = hdfs.append(bar);
out.write(testData);
out.close();
INodeFile barNode = fsdir.getINode4Write(bar.toString()).asFile();
BlockInfo[] blks = barNode.getBlocks();
assertEquals(1, blks.length);
assertEquals(testData.length, blks[0].getNumBytes());
// Delete the file.
hdfs.delete(bar, true);
// Now make sure that the NN can still save an fsimage successfully.
cluster.getNameNode().getRpcServer().setSafeMode(
SafeModeAction.SAFEMODE_ENTER, false);
cluster.getNameNode().getRpcServer().saveNamespace();
}
}