Index: hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSHDFSUtils.java =================================================================== --- hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSHDFSUtils.java (revision 1449791) +++ hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSHDFSUtils.java (working copy) @@ -72,22 +72,32 @@ // Trying recovery boolean recovered = false; + long recoveryTimeout = conf.getInt("hbase.lease.recovery.timeout", 300000); + Exception ex = null; while (!recovered) { try { try { DistributedFileSystem dfs = (DistributedFileSystem) fs; - DistributedFileSystem.class.getMethod("recoverLease", new Class[] { Path.class }).invoke( - dfs, p); + recovered = (Boolean) DistributedFileSystem.class.getMethod( + "recoverLease", new Class[] { Path.class }).invoke(dfs, p); } catch (InvocationTargetException ite) { // function was properly called, but threw it's own exception throw (IOException) ite.getCause(); } catch (Exception e) { - LOG.debug("Failed fs.recoverLease invocation, " + e.toString() + - ", trying fs.append instead"); + // hdfs 2.0 may throw RecoveryInProgressException + if (!e.getClass().getName().contains("RecoveryInProgressException")) { + LOG.debug("Failed fs.recoverLease invocation, " + e.toString() + + ", trying fs.append instead"); + ex = e; + } + } + if (ex != null || System.currentTimeMillis() - startWaiting > recoveryTimeout) { + ex = null; // assume the following append() call would succeed FSDataOutputStream out = fs.append(p); out.close(); + recovered = true; } - recovered = true; + if (recovered) break; } catch (IOException e) { e = RemoteExceptionHandler.checkIOException(e); if (e instanceof AlreadyBeingCreatedException) { @@ -111,9 +121,9 @@ } try { Thread.sleep(1000); - } catch (InterruptedException ex) { + } catch (InterruptedException ie) { InterruptedIOException iioe = new InterruptedIOException(); - iioe.initCause(ex); + iioe.initCause(ie); throw iioe; } }