HDFS-13813. Exit NameNode if dangling child inode is detected when saving FsImage. Contributed by Siyao Meng.
This commit is contained in:
parent
74411ce0ce
commit
23854443ef
|
@ -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() {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue