HDFS-13813. Exit NameNode if dangling child inode is detected when saving FsImage. Contributed by Siyao Meng.

This commit is contained in:
Wei-Chiu Chuang 2018-08-13 16:12:37 -07:00
parent 74411ce0ce
commit 23854443ef
2 changed files with 32 additions and 5 deletions

View File

@ -439,6 +439,8 @@ public final class FSImageFormatPBINode {
} }
public final static class Saver { public final static class Saver {
private long numImageErrors;
private static long buildPermissionStatus(INodeAttributes n, private static long buildPermissionStatus(INodeAttributes n,
final SaverContext.DeduplicationMap<String> stringMap) { final SaverContext.DeduplicationMap<String> stringMap) {
long userId = stringMap.getId(n.getUserName()); long userId = stringMap.getId(n.getUserName());
@ -563,11 +565,13 @@ public final class FSImageFormatPBINode {
this.summary = summary; this.summary = summary;
this.context = parent.getContext(); this.context = parent.getContext();
this.fsn = context.getSourceNamesystem(); this.fsn = context.getSourceNamesystem();
this.numImageErrors = 0;
} }
void serializeINodeDirectorySection(OutputStream out) throws IOException { void serializeINodeDirectorySection(OutputStream out) throws IOException {
Iterator<INodeWithAdditionalFields> iter = fsn.getFSDirectory() FSDirectory dir = fsn.getFSDirectory();
.getINodeMap().getMapIterator(); Iterator<INodeWithAdditionalFields> iter = dir.getINodeMap()
.getMapIterator();
final ArrayList<INodeReference> refList = parent.getSaverContext() final ArrayList<INodeReference> refList = parent.getSaverContext()
.getRefList(); .getRefList();
int i = 0; int i = 0;
@ -583,6 +587,17 @@ public final class FSImageFormatPBINode {
INodeDirectorySection.DirEntry.Builder b = INodeDirectorySection. INodeDirectorySection.DirEntry.Builder b = INodeDirectorySection.
DirEntry.newBuilder().setParent(n.getId()); DirEntry.newBuilder().setParent(n.getId());
for (INode inode : children) { for (INode inode : children) {
// Error if the child inode doesn't exist in inodeMap
if (dir.getInode(inode.getId()) == null) {
FSImage.LOG.error(
"FSImageFormatPBINode#serializeINodeDirectorySection: " +
"Dangling child pointer found. Missing INode in " +
"inodeMap: id=" + inode.getId() +
"; path=" + inode.getFullPathName() +
"; parent=" + (inode.getParent() == null ? "null" :
inode.getParent().getFullPathName()));
++numImageErrors;
}
if (!inode.isReference()) { if (!inode.isReference()) {
b.addChildren(inode.getId()); b.addChildren(inode.getId());
} else { } else {
@ -711,6 +726,15 @@ public final class FSImageFormatPBINode {
.setId(n.getId()) .setId(n.getId())
.setName(ByteString.copyFrom(n.getLocalNameBytes())); .setName(ByteString.copyFrom(n.getLocalNameBytes()));
} }
/**
* Number of non-fatal errors detected while writing the
* INodeSection and INodeDirectorySection sections.
* @return the number of non-fatal errors detected.
*/
public long getNumImageErrors() {
return numImageErrors;
}
} }
private FSImageFormatPBINode() { private FSImageFormatPBINode() {

View File

@ -474,13 +474,15 @@ public final class FSImageFormatProtobuf {
out.write(lengthBytes); out.write(lengthBytes);
} }
private void saveInodes(FileSummary.Builder summary) throws IOException { private long saveInodes(FileSummary.Builder summary) throws IOException {
FSImageFormatPBINode.Saver saver = new FSImageFormatPBINode.Saver(this, FSImageFormatPBINode.Saver saver = new FSImageFormatPBINode.Saver(this,
summary); summary);
saver.serializeINodeSection(sectionOutputStream); saver.serializeINodeSection(sectionOutputStream);
saver.serializeINodeDirectorySection(sectionOutputStream); saver.serializeINodeDirectorySection(sectionOutputStream);
saver.serializeFilesUCSection(sectionOutputStream); saver.serializeFilesUCSection(sectionOutputStream);
return saver.getNumImageErrors();
} }
/** /**
@ -543,8 +545,9 @@ public final class FSImageFormatProtobuf {
step = new Step(StepType.INODES, filePath); step = new Step(StepType.INODES, filePath);
prog.beginStep(Phase.SAVING_CHECKPOINT, step); prog.beginStep(Phase.SAVING_CHECKPOINT, step);
saveInodes(b); // Count number of non-fatal errors when saving inodes and snapshots.
long numErrors = saveSnapshots(b); long numErrors = saveInodes(b);
numErrors += saveSnapshots(b);
prog.endStep(Phase.SAVING_CHECKPOINT, step); prog.endStep(Phase.SAVING_CHECKPOINT, step);
step = new Step(StepType.DELEGATION_TOKENS, filePath); step = new Step(StepType.DELEGATION_TOKENS, filePath);