You are viewing a plain text version of this content. The canonical link for it is here.
Posted to common-commits@hadoop.apache.org by dh...@apache.org on 2007/09/19 18:58:49 UTC
svn commit: r577372 - in /lucene/hadoop/trunk: CHANGES.txt
src/java/org/apache/hadoop/dfs/BlocksMap.java
src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java
Author: dhruba
Date: Wed Sep 19 09:58:49 2007
New Revision: 577372
URL: http://svn.apache.org/viewvc?rev=577372&view=rev
Log:
HADOOP-1904. The Namenode encounters an exception because the
list of blocks per datanode-descriptor was corrupted.
Modified:
lucene/hadoop/trunk/CHANGES.txt
lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/BlocksMap.java
lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java
Modified: lucene/hadoop/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/CHANGES.txt?rev=577372&r1=577371&r2=577372&view=diff
==============================================================================
--- lucene/hadoop/trunk/CHANGES.txt (original)
+++ lucene/hadoop/trunk/CHANGES.txt Wed Sep 19 09:58:49 2007
@@ -83,6 +83,10 @@
BUG FIXES
+ HADOOP-1904. The Namenode encounters an exception because the
+ list of blocks per datanode-descriptor was corrupted.
+ (Konstantin Shvachko via dhruba)
+
HADOOP-1762. The Namenode fsimage does not contain a list of
Datanodes. (Raghu Angadi via dhruba)
Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/BlocksMap.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/BlocksMap.java?rev=577372&r1=577371&r2=577372&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/BlocksMap.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/BlocksMap.java Wed Sep 19 09:58:49 2007
@@ -142,14 +142,13 @@
* Add data-node this block belongs to.
*/
boolean addNode(DatanodeDescriptor node) {
- int dnIndex = this.findDatanode(node);
- if(dnIndex >= 0) // the node is already there
+ if(findDatanode(node) >= 0) // the node is already there
return false;
// find the last null node
int lastNode = ensureCapacity(1);
setDatanode(lastNode, node);
- setNext(lastNode, null);
- setPrevious(lastNode, null);
+ setNext(lastNode, null);
+ setPrevious(lastNode, null);
return true;
}
@@ -160,6 +159,8 @@
int dnIndex = this.findDatanode(node);
if(dnIndex < 0) // the node is not found
return false;
+ assert getPrevious(dnIndex) == null && getNext(dnIndex) == null :
+ "Block is still in the list and must be removed first.";
// find the last not null node
int lastNode = numNodes()-1;
// replace current node triplet by the lastNode one
@@ -199,13 +200,12 @@
BlockInfo listInsert(BlockInfo head, DatanodeDescriptor dn) {
int dnIndex = this.findDatanode(dn);
assert dnIndex >= 0 : "Data node is not found: current";
+ assert getPrevious(dnIndex) == null && getNext(dnIndex) == null :
+ "Block is already in the list and cannot be inserted.";
this.setPrevious(dnIndex, null);
this.setNext(dnIndex, head);
- if(head != null) {
- int headDNIndex = head.findDatanode(dn);
- assert headDNIndex >= 0 : "Data node is not found: head";
- head.setPrevious(headDNIndex, this);
- }
+ if(head != null)
+ head.setPrevious(head.findDatanode(dn), this);
return this;
}
@@ -228,16 +228,10 @@
BlockInfo prev = this.getPrevious(dnIndex);
this.setNext(dnIndex, null);
this.setPrevious(dnIndex, null);
- if(prev != null) {
- int prevDNIndex = prev.findDatanode(dn);
- assert prevDNIndex >= 0 : "Data node is not found: previous";
- prev.setNext(prevDNIndex, next);
- }
- if(next != null) {
- int nextDNIndex = next.findDatanode(dn);
- assert nextDNIndex >= 0 : "Data node is not found: next";
- next.setPrevious(nextDNIndex, prev);
- }
+ if(prev != null)
+ prev.setNext(prev.findDatanode(dn), next);
+ if(next != null)
+ next.setPrevious(next.findDatanode(dn), prev);
if(this == head) // removing the head
head = next;
return head;
@@ -250,6 +244,26 @@
count++;
return count;
}
+
+ boolean listIsConsistent(DatanodeDescriptor dn) {
+ // going forward
+ int count = 0;
+ BlockInfo next, nextPrev;
+ BlockInfo cur = this;
+ while(cur != null) {
+ next = cur.getNext(cur.findDatanode(dn));
+ if(next != null) {
+ nextPrev = next.getPrevious(next.findDatanode(dn));
+ if(cur != nextPrev) {
+ System.out.println("Inconsistent list: cur->next->prev != cur");
+ return false;
+ }
+ }
+ cur = next;
+ count++;
+ }
+ return true;
+ }
}
private static class NodeIterator implements Iterator<DatanodeDescriptor> {
@@ -277,7 +291,8 @@
private Map<Block, BlockInfo> map = new HashMap<Block, BlockInfo>();
/**
- * Add BlockInfo if mapping does not exist. */
+ * Add BlockInfo if mapping does not exist.
+ */
private BlockInfo checkBlockInfo(Block b, int replication) {
BlockInfo info = map.get(b);
if (info == null) {
@@ -337,11 +352,8 @@
boolean addNode(Block b, DatanodeDescriptor node, int replication) {
// insert into the map if not there yet
BlockInfo info = checkBlockInfo(b, replication);
- // add node to the block info
- boolean added = info.addNode(node);
- // add to the data-node list
- node.addBlock(info);
- return added;
+ // add block to the data-node list and the node to the block info
+ return node.addBlock(info);
}
/**
@@ -353,10 +365,10 @@
BlockInfo info = map.get(b);
if (info == null)
return false;
- // first remove block from the data-node list
- node.removeBlock(info);
- // remove node from the block info
- boolean removed = info.removeNode(node);
+
+ // remove block from the data-node list and the node from the block info
+ boolean removed = node.removeBlock(info);
+
if (info.getDatanode(0) == null // no datanodes left
&& info.inode == null) { // does not belong to a file
map.remove(b); // remove block from the map
Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java
URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java?rev=577372&r1=577371&r2=577372&view=diff
==============================================================================
--- lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java (original)
+++ lucene/hadoop/trunk/src/java/org/apache/hadoop/dfs/DatanodeDescriptor.java Wed Sep 19 09:58:49 2007
@@ -132,17 +132,32 @@
}
/**
+ * Add data-node to the block.
* Add block to the head of the list of blocks belonging to the data-node.
*/
- void addBlock(BlockInfo b) {
+ boolean addBlock(BlockInfo b) {
+ if(!b.addNode(this))
+ return false;
+ // add to the head of the data-node list
blockList = b.listInsert(blockList, this);
+ return true;
}
/**
* Remove block from the list of blocks belonging to the data-node.
+ * Remove data-node from the block.
*/
- void removeBlock(BlockInfo b) {
+ boolean removeBlock(BlockInfo b) {
blockList = b.listRemove(blockList, this);
+ return b.removeNode(this);
+ }
+
+ /**
+ * Move block to the head of the list of blocks belonging to the data-node.
+ */
+ void moveBlockToHead(BlockInfo b) {
+ blockList = b.listRemove(blockList, this);
+ blockList = b.listInsert(blockList, this);
}
void resetBlocks() {
@@ -167,6 +182,9 @@
this.xceiverCount = xceiverCount;
}
+ /**
+ * Iterates over the list of blocks belonging to the data-node.
+ */
static private class BlockIterator implements Iterator<Block> {
private BlockInfo current;
private DatanodeDescriptor node;
@@ -303,11 +321,14 @@
Block[] newReport,
Collection<Block> toAdd,
Collection<Block> toRemove) {
+ // place a deilimiter in the list which separates blocks
+ // that have been reported from those that have not
BlockInfo delimiter = new BlockInfo(new Block(), 1);
- delimiter.addNode(this);
- this.addBlock(delimiter); // add to the head of the list
+ boolean added = this.addBlock(delimiter);
+ assert added : "Delimiting block cannot be present in the node";
if(newReport == null)
newReport = new Block[0];
+ // scan the report and collect newly reported blocks
for(Block blk : newReport) {
BlockInfo storedBlock = blocksMap.getStoredBlock(blk);
if(storedBlock == null || storedBlock.findDatanode(this) < 0) {
@@ -315,11 +336,10 @@
continue;
}
// move block to the head of the list
- this.removeBlock(storedBlock);
- this.addBlock(storedBlock);
+ this.moveBlockToHead(storedBlock);
}
// collect blocks that have not been reported
- // they are all next to the delimiter
+ // all of them are next to the delimiter
Iterator<Block> it = new BlockIterator(delimiter.getNext(0), this);
while(it.hasNext())
toRemove.add(it.next());