Author: szetszwo
Date: Wed Dec 10 16:50:15 2008
New Revision: 725507
URL: http://svn.apache.org/viewvc?rev=725507&view=rev
Log:
HADOOP-4795. Prevent lease monitor getting into an infinite loop when leases
and the namespace tree does not match. (szetszwo)
Modified:
hadoop/core/trunk/CHANGES.txt
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/LeaseManager.java
Modified: hadoop/core/trunk/CHANGES.txt
URL:
http://svn.apache.org/viewvc/hadoop/core/trunk/CHANGES.txt?rev=725507&r1=725506&r2=725507&view=diff
==============================================================================
--- hadoop/core/trunk/CHANGES.txt (original)
+++ hadoop/core/trunk/CHANGES.txt Wed Dec 10 16:50:15 2008
@@ -1415,6 +1415,9 @@
HADOOP-4806. HDFS rename should not use src path as a regular expression.
(szetszwo)
+ HADOOP-4795. Prevent lease monitor getting into an infinite loop when
+ leases and the namespace tree does not match. (szetszwo)
+
Release 0.18.2 - 2008-11-03
BUG FIXES
Modified:
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
URL:
http://svn.apache.org/viewvc/hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java?rev=725507&r1=725506&r2=725507&view=diff
==============================================================================
---
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
(original)
+++
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java
Wed Dec 10 16:50:15 2008
@@ -308,7 +308,7 @@
conf.getInt("dfs.replication.pending.timeout.sec",
-1) * 1000L);
this.hbthread = new Daemon(new HeartbeatMonitor());
- this.lmthread = new Daemon(leaseManager.createMonitor());
+ this.lmthread = new Daemon(leaseManager.new Monitor());
this.replthread = new Daemon(new ReplicationMonitor());
hbthread.start();
lmthread.start();
@@ -1779,20 +1779,18 @@
INodeFile iFile = dir.getFileINode(src);
if (iFile == null) {
- NameNode.stateChangeLog.warn("DIR* NameSystem.internalReleaseCreate: "
- + "attempt to release a create lock on "
- + src + " file does not exist.");
- return;
+ final String message = "DIR* NameSystem.internalReleaseCreate: "
+ + "attempt to release a create lock on "
+ + src + " file does not exist.";
+ NameNode.stateChangeLog.warn(message);
+ throw new IOException(message);
}
if (!iFile.isUnderConstruction()) {
- NameNode.stateChangeLog.warn("DIR* NameSystem.internalReleaseCreate: "
- + "attempt to release a create lock on "
- + src + " but file is already closed.");
- return;
- }
- if (NameNode.stateChangeLog.isDebugEnabled()) {
- NameNode.stateChangeLog.debug("DIR* NameSystem.internalReleaseCreate: "
- + src + " does not being written in " + lease);
+ final String message = "DIR* NameSystem.internalReleaseCreate: "
+ + "attempt to release a create lock on "
+ + src + " but file is already closed.";
+ NameNode.stateChangeLog.warn(message);
+ throw new IOException(message);
}
INodeFileUnderConstruction pendingFile = (INodeFileUnderConstruction)
iFile;
Modified:
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/LeaseManager.java
URL:
http://svn.apache.org/viewvc/hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/LeaseManager.java?rev=725507&r1=725506&r2=725507&view=diff
==============================================================================
---
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/LeaseManager.java
(original)
+++
hadoop/core/trunk/src/hdfs/org/apache/hadoop/hdfs/server/namenode/LeaseManager.java
Wed Dec 10 16:50:15 2008
@@ -331,43 +331,54 @@
this.hardLimit = hardLimit;
}
- Monitor createMonitor() {return new Monitor();}
-
/******************************************************
* Monitor checks for leases that have expired,
* and disposes of them.
******************************************************/
class Monitor implements Runnable {
+ final String name = getClass().getSimpleName();
+
+ /** Check leases periodically. */
public void run() {
- try {
- while (fsnamesystem.isRunning()) {
- synchronized (fsnamesystem) {
- synchronized (LeaseManager.this) {
- Lease top;
- while ((sortedLeases.size() > 0) &&
- ((top = sortedLeases.first()) != null)) {
- if (top.expiredHardLimit()) {
- LOG.info("Lease Monitor: Removing lease " + top
- + ", sortedLeases.size()=: " + sortedLeases.size());
- for(String s : top.paths) {
- fsnamesystem.internalReleaseLease(top, s);
- }
- } else {
- break;
- }
- }
- }
+ for(; fsnamesystem.isRunning(); ) {
+ synchronized(fsnamesystem) {
+ checkLeases();
+ }
+
+ try {
+ Thread.sleep(2000);
+ } catch(InterruptedException ie) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug(name + " is interrupted", ie);
}
+ }
+ }
+ }
+
+ /** Check the leases beginning from the oldest. */
+ private synchronized void checkLeases() {
+ for(; sortedLeases.size() > 0; ) {
+ final Lease oldest = sortedLeases.first();
+ if (!oldest.expiredHardLimit()) {
+ return;
+ }
+
+ LOG.info(name + ": Lease " + oldest + " has expired hard limit");
+
+ final List<String> removing = new ArrayList<String>();
+ for(String p : oldest.getPaths()) {
try {
- Thread.sleep(2000);
- } catch(InterruptedException ie) {
- if (LOG.isDebugEnabled()) {
- LOG.debug(getClass().getName() + " is interrupted", ie);
- }
+ fsnamesystem.internalReleaseLease(oldest, p);
+ } catch (IOException e) {
+ LOG.error("In " + name + ", cannot release the path " + p
+ + " in the lease " + oldest, e);
+ removing.add(p);
}
}
- } catch(Exception e) {
- LOG.error("In " + getClass().getName(), e);
+
+ for(String p : removing) {
+ removeLease(oldest, p);
+ }
}
}
}