Index: src/main/java/org/apache/hadoop/hbase/regionserver/handler/OpenRegionHandler.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/regionserver/handler/OpenRegionHandler.java (revision 1441742) +++ src/main/java/org/apache/hadoop/hbase/regionserver/handler/OpenRegionHandler.java (working copy) @@ -84,6 +84,8 @@ @Override public void process() throws IOException { + boolean transitionToFailedOpen = false; + boolean openSuccessful = false; try { final String name = regionInfo.getRegionNameAsString(); if (this.server.isStopped() || this.rsServices.isStopping()) { @@ -120,6 +122,7 @@ this.rsServices.isStopping()) { cleanupFailedOpen(region); tryTransitionToFailedOpen(regionInfo); + transitionToFailedOpen = true; return; } @@ -131,17 +134,21 @@ // In case (a), the Master will process us as a dead server. In case // (b) the region is already being handled elsewhere anyway. cleanupFailedOpen(region); + transitionToFailedOpen = true; return; } // Successful region open, and add it to OnlineRegions this.rsServices.addToOnlineRegions(region); - + openSuccessful = true; // Done! Successful region open LOG.debug("Opened " + name + " on server:" + this.server.getServerName()); } finally { this.rsServices.getRegionsInTransitionInRS(). remove(this.regionInfo.getEncodedNameAsBytes()); + if (!openSuccessful && !transitionToFailedOpen) { + tryTransitionToFailedOpen(regionInfo); + } } } @@ -359,7 +366,7 @@ return region; } - private void cleanupFailedOpen(final HRegion region) throws IOException { + void cleanupFailedOpen(final HRegion region) throws IOException { if (region != null) region.close(); } Index: src/test/java/org/apache/hadoop/hbase/regionserver/handler/TestOpenRegionHandler.java =================================================================== --- src/test/java/org/apache/hadoop/hbase/regionserver/handler/TestOpenRegionHandler.java (revision 1441742) +++ src/test/java/org/apache/hadoop/hbase/regionserver/handler/TestOpenRegionHandler.java (working copy) @@ -178,7 +178,36 @@ assertEquals(EventType.RS_ZK_REGION_FAILED_OPEN, data.getEventType()); } + @Test + public void testTransitionToFailedOpenEvenIfCleanupFails() throws Exception { + Server server = new MockServer(HTU); + RegionServerServices rsServices = new MockRegionServerServices(); + // Create it OFFLINE, which is what it expects + ZKAssign.createNodeOffline(server.getZooKeeper(), TEST_HRI, server.getServerName()); + // Create the handler + OpenRegionHandler handler = new OpenRegionHandler(server, rsServices, TEST_HRI, TEST_HTD) { + @Override + boolean updateMeta(HRegion r) { + return false; + }; + @Override + void cleanupFailedOpen(HRegion region) throws IOException { + throw new IOException("FileSystem got closed."); + } + }; + rsServices.getRegionsInTransitionInRS().put(TEST_HRI.getEncodedNameAsBytes(), Boolean.TRUE); + try { + handler.process(); + } catch (Exception e) { + // Ignore the IOException that we have thrown from cleanupFailedOpen + } + RegionTransitionData data = + ZKAssign.getData(server.getZooKeeper(), TEST_HRI.getEncodedName()); + assertEquals(EventType.RS_ZK_REGION_FAILED_OPEN, data.getEventType()); + } + + @org.junit.Rule public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu = new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();