Index: src/main/java/org/apache/hadoop/hbase/catalog/CatalogTracker.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/catalog/CatalogTracker.java (revision 1221103) +++ src/main/java/org/apache/hadoop/hbase/catalog/CatalogTracker.java (working copy) @@ -42,8 +42,10 @@ import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.zookeeper.MetaNodeTracker; import org.apache.hadoop.hbase.zookeeper.RootRegionTracker; +import org.apache.hadoop.hbase.zookeeper.ZKUtil; import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher; import org.apache.hadoop.ipc.RemoteException; +import org.apache.zookeeper.KeeperException; /** * Tracks the availability of the catalog tables -ROOT- and @@ -343,9 +345,16 @@ * @throws InterruptedException if interrupted while waiting */ public void waitForMeta() throws InterruptedException { - synchronized (metaAvailable) { - while (!stopped && !metaAvailable.get()) { - metaAvailable.wait(); + while (!this.stopped) { + try { + if (waitForMeta(100) != null) break; + } catch (NotAllMetaRegionsOnlineException e) { + if (LOG.isTraceEnabled()) { + LOG.info(".META. still not available, sleeping and retrying." + + " Reason: " + e.getMessage()); + } + } catch (IOException e) { + LOG.info("Retrying", e); } } } @@ -372,6 +381,21 @@ if (getMetaServerConnection(true) != null) { return metaLocation; } + // chk if the shutdown node is available. Because incase of cluster + // shutdonw + // this loop prevents the master from going down. + try { + if (ZKUtil.checkExists(zookeeper, zookeeper.clusterStateZNode) == -1) { + LOG.info("Cluster shutdown was requested. Hence shutting down."); + this.stopped = true; + metaAvailable.notifyAll(); + } + } catch (KeeperException e) { + abortable + .abort( + "Unexpected exception handling while checking if shutdown node exists.", + e); + } metaAvailable.wait(timeout == 0 ? 50 : timeout); } if (getMetaServerConnection(true) == null) { Index: src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (revision 1221103) +++ src/main/java/org/apache/hadoop/hbase/master/AssignmentManager.java (working copy) @@ -1313,7 +1313,7 @@ public void waitForAssignment(HRegionInfo regionInfo) throws InterruptedException { synchronized(regions) { - while(!regions.containsKey(regionInfo)) { + while(!this.master.isStopped() && !regions.containsKey(regionInfo)) { regions.wait(); } } Index: src/main/java/org/apache/hadoop/hbase/master/HMaster.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/master/HMaster.java (revision 1221103) +++ src/main/java/org/apache/hadoop/hbase/master/HMaster.java (working copy) @@ -374,6 +374,9 @@ // Wait for region servers to report in. Returns count of regions. int regionCount = this.serverManager.waitForRegionServers(); + if (this.stopped) { + return; + } // TODO: Should do this in background rather than block master startup this.fileSystemManager. @@ -425,6 +428,7 @@ if (!catalogTracker.verifyRootRegionLocation(timeout)) { this.assignmentManager.assignRoot(); this.catalogTracker.waitForRoot(); + if(this.stopped) return 0; //This guarantees that the transition has completed this.assignmentManager.waitForAssignment(HRegionInfo.ROOT_REGIONINFO); assigned++; @@ -438,6 +442,7 @@ if (!this.catalogTracker.verifyMetaRegionLocation(timeout)) { this.assignmentManager.assignMeta(); this.catalogTracker.waitForMeta(); + if(this.stopped) return 0; // Above check waits for general meta availability but this does not // guarantee that the transition has completed this.assignmentManager.waitForAssignment(HRegionInfo.FIRST_META_REGIONINFO); Index: src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperNodeTracker.java =================================================================== --- src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperNodeTracker.java (revision 1221103) +++ src/main/java/org/apache/hadoop/hbase/zookeeper/ZooKeeperNodeTracker.java (working copy) @@ -19,6 +19,8 @@ */ package org.apache.hadoop.hbase.zookeeper; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.apache.hadoop.hbase.Abortable; import org.apache.zookeeper.KeeperException; @@ -32,6 +34,8 @@ * RegionServers. */ public abstract class ZooKeeperNodeTracker extends ZooKeeperListener { + + static final Log LOG = LogFactory.getLog(ZooKeeperNodeTracker.class); /** Path of node being tracked */ protected final String node; @@ -115,6 +119,20 @@ long startTime = System.currentTimeMillis(); long remaining = timeout; while (!this.stopped && (notimeout || remaining > 0) && this.data == null) { + // chk if the shutdown node is available. Because incase of cluster + // shutdonw + // this loop prevents the master from going down. + try { + if (ZKUtil.checkExists(watcher, watcher.clusterStateZNode) == -1) { + LOG.info("Cluster shutdown was requested. Hence shutting down."); + this.stopped = true; + } + } catch (KeeperException e) { + abortable + .abort( + "Unexpected exception handling while checking if shutdown node exists.", + e); + } if (notimeout) { wait(); continue;